C

时间:2016-02-08 15:18:55

标签: c arrays pointers

所以我一直在尝试将PPM文件存储在要操作的程序中,我成功地将所有内容存储到颜色中,我在颜色上取得了进展。

在询问有关堆栈溢出的问题(For loop stops for no reason)时,我确信我的方法有点粗制滥造,但我不明白使用以下内容的原因:

COLOR (*colors)[width] = malloc( sizeof(COLOR[height][width]) );

有人可以完全分解这行代码正在做什么并解释它是什么类型。所以我可以将它存储在一个结构中并成功返回它。

实施例: 以前我使用指针指针,我分配了一个高度,每个指针都分配了一个宽度。这意味着对于每个指针,我可以创建一个颜色,沿着宽度递增它,直到Im结束,然后重置指针并增加高度和循环。获得完整图像后,我将其返回以存储在以下内容中:

typedef struct {
    char code[CODE_LENGTH];
    COMMENT *commentPPM;
    int width, height, max;
    COLOR **colorValues;
} PPM;

使用:

ppmFile->colorValues = getColors(fd, ppmFile->width, ppmFile->height);

typedef struct{
    int red, green, blue;
} COLOR;

COLOR * getNextColor(FILE *fd);

COLOR **getColors(FILE *fd, int width, int height){
    printf("\nentered get colors");
    COLOR **colors = malloc(sizeof(COLOR*)*height);
    printf("\nallocated %d space height",height);

    int i,j;
    for(i = 0; i < height; i++, colors++){
        *colors = malloc(sizeof(COLOR)*width);
        printf("\nallocated %d space width",width);
        for(j = 0; j < width; j++, *(colors++)){
            printf("\nlooping through to get the colors for point (%d,%d)", j,i); 
            //*colors = getNextColor(fd);
        }
        *colors -= width;
        printf("\nmoved the pointer for *colors back %d spaces",width);
    }

    colors -= height;
    printf("\nmoved the pointer for colors back %d spaces",height);

    return colors;
}

1 个答案:

答案 0 :(得分:3)

为了理解这一点,您需要先了解这些概念:

  • 数组指针(不要与指向第一个元素的指针混淆)
  • 可变长度数组,也称为VLA。

鉴于已经知道上面是什么,那么最正式的方法是声明一个指向2D VLA的数组指针:

COLOR (*colors)[height][width];

当你调用malloc时,你告诉它为这样的数组分配足够的空间:

malloc( sizeof(COLOR[height][width]) )

然后你会以

结束
colors = malloc( sizeof(COLOR[height][width]) );

但是,由于此示例中的colors是数组指针,因此每次要访问数组时都必须取消引用它:

(*colors)[i][j] = something;

此语法不实用且难以阅读。

因此,您可以使用另一个技巧,并在声明数组指针时跳过最里面的维度。您可以跳过最里面的维度,而只是声明指向1D数组的数组指针,而不是指向2D数组的指针:

COLOR (*colors)[width]

但使用与之前完全相同的malloc调用。因为现在你可以利用数组指针算法:

colors[i][j] = something;

本质上意味着,“在我的数组数组中,给我数组i,项目编号j”。

它与int* x = malloc(sizeof(int[n])); ... x[i] = something;的工作原理相同,当然会为您提供int个数字i