mor*_*y95 4 c arrays struct variable-length-array
我创建了2个结构来表示C中的图像(一个像素和一个图像)。
typedef struct pixel {
unsigned char red;
unsigned char green;
unsigned char blue;
};
typedef struct image {
int width;
int heigth;
struct pixel pixels[width][heigth];
};
Run Code Online (Sandbox Code Playgroud)
我收到一个错误消息,说图像的定义中未定义宽度和高度。我不明白为什么会收到该错误以及如何解决该错误
在C99和更高版本中,您可以在结构的末尾拥有一个(一维)柔性数组成员(FAM):
第6.7.2.1节结构和联合说明符
¶18作为一种特殊情况,结构中具有多个命名成员的最后一个元素可能具有不完整的数组类型。这称为弹性数组成员。在大多数情况下,柔性数组成员将被忽略。特别地,该结构的尺寸就好像省略了柔性阵列构件,除了其可能具有比省略所暗示的更多的尾随填充。然而,当一个
.(或->)运算符的左操作数是一个指向具有灵活数组成员的结构的指针(指向该成员的结构),右操作数为该成员的名称,它的行为就好像该成员被最长的数组(具有相同的元素类型)替换,而该数组不会使结构大于要访问的对象;即使该阵列的偏移量与替换阵列的偏移量不同,其偏移量也应保持为柔性阵列成员的偏移量。如果此数组不包含任何元素,则其行为就好像它具有一个元素,但是如果尝试访问该元素或生成一个指针经过该元素,则该行为未定义。
这意味着您可以编写:
typedef struct image
{
int width;
int height;
struct pixel pixels[];
} image;
Run Code Online (Sandbox Code Playgroud)
但您必须自己进行2D到1D索引映射。您还必须注意如何分配结构(必不可少的是,它将被分配,malloc()否则数组的大小将为零)。
注意的拼写修正height; 请注意还要为添加一个名称typedef(我选择image匹配structure标签,但是您可以选择其他任何喜欢的名称)。typedef没有名称的A 是“有效”但没有用-您可以省略typedef并获得相同的结果。
您可以使用:
image *ip = malloc(sizeof(image) + width * height * sizeof(struct pixel));
if (ip != 0)
{
ip->width = width;
ip->height = height;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
ip->pixels[i*width + j] = default_pixel_value;
}
…use ip…
free(ip);
}
Run Code Online (Sandbox Code Playgroud)
我不确定是否有一种好的方法可以将2D阵列用作FAM。
我建议像这样的替代方案:
typedef struct
{
int width;
int height;
struct pixel *pixels;
} image;
Run Code Online (Sandbox Code Playgroud)
每次,您都需要分配:
image img;
/* init */
img.pixels=malloc(sizeof(struct pixel)*img.width*img.height);
Run Code Online (Sandbox Code Playgroud)
*(img.pixels+img.height*i+j)代表img.pixels[i][j]。