C中的可变大小二维数组

时间:2021-08-02 20:25:43

So I've been trying to store a PPM file in a program to be manipulated, I successful stored everything up to the colors, I've made progress on the colors.

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

During asking a question on stack overflow (For loop stops for no reason) I was convinced that my method was a bit shoddy, however I don't understand the reasoning for using the follow:

在询问有关堆栈溢出的问题时(对于循环停止无理由)我确信我的方法有点粗制滥造,但是我不明白使用以下内容的原因:

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

can someone break down exactly what this line of code is doing and explain what type it is. So I can store it in a struct and successful return it.

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

Example: previously I used pointers to pointers, where I allocated a height and for each pointer I allocated a width. This means that for each pointer I could create a color, increment it along the width until Im at the end, then reset the pointer and increment the height and loop. After I got the full image I return it to store it in the follow:

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

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

using:

使用:

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

and

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 个解决方案

#1


2  

In order to understand this, you need to first understand the concepts:

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

  • Array pointers (not to be confused with pointer to first element)
  • 数组指针(不要与指向第一个元素的指针混淆)
  • Variable-length arrays, also known as VLAs.
  • 可变长度阵列,也称为VLA。

Given that already you know what the above is, then the most formally proper way to do this is to declare an array pointer to a 2D VLA:

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

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

And when you call malloc, you tell it to allocate enough space for such an array:

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

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

You would then end up with

然后你会结束

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

However, since colors in this example is an array pointer, you would have to de-reference it each time you wish to access the array:

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

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

This syntax is not practical and also hard to read.

这种语法不实用,也很难阅读。

Therefore, you can use another trick and skip the inner-most dimension when you declare the array pointer. Instead of a pointer to a 2D array, you could skip the inner-most dimension and just declare an array pointer to a 1D array:

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

COLOR (*colors)[width]

but use this with the very same malloc call as before. Because now you can take advantage of array pointer arithmetic:

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

colors[i][j] = something;

Which essentially means, "in my array-of-arrays, give me array number i, item number j".

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

It works for the same reason as int* x = malloc(sizeof(int[n])); ... x[i] = something; works, which of course gives you int number i.

它的工作原理与int * x = malloc(sizeof(int [n]))相同; ...... x [i] =某事;工作,当然给你int号码i。

#1


2  

In order to understand this, you need to first understand the concepts:

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

  • Array pointers (not to be confused with pointer to first element)
  • 数组指针(不要与指向第一个元素的指针混淆)
  • Variable-length arrays, also known as VLAs.
  • 可变长度阵列,也称为VLA。

Given that already you know what the above is, then the most formally proper way to do this is to declare an array pointer to a 2D VLA:

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

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

And when you call malloc, you tell it to allocate enough space for such an array:

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

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

You would then end up with

然后你会结束

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

However, since colors in this example is an array pointer, you would have to de-reference it each time you wish to access the array:

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

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

This syntax is not practical and also hard to read.

这种语法不实用,也很难阅读。

Therefore, you can use another trick and skip the inner-most dimension when you declare the array pointer. Instead of a pointer to a 2D array, you could skip the inner-most dimension and just declare an array pointer to a 1D array:

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

COLOR (*colors)[width]

but use this with the very same malloc call as before. Because now you can take advantage of array pointer arithmetic:

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

colors[i][j] = something;

Which essentially means, "in my array-of-arrays, give me array number i, item number j".

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

It works for the same reason as int* x = malloc(sizeof(int[n])); ... x[i] = something; works, which of course gives you int number i.

它的工作原理与int * x = malloc(sizeof(int [n]))相同; ...... x [i] =某事;工作,当然给你int号码i。