提问人:moray95 提问时间:10/4/2014 最后编辑:Jonathan Lefflermoray95 更新时间:7/29/2022 访问量:10217
结构中可变长度的数组
Array of variable length in a structure
问:
我创建了 2 个结构来表示 C 语言中的图像(一个像素和一个图像)。
typedef struct pixel {
unsigned char red;
unsigned char green;
unsigned char blue;
};
typedef struct image {
int width;
int height;
struct pixel pixels[width][height];
};
我收到一个错误,说宽度和高度未在图像结构的定义中定义。我不明白为什么我会遇到这个错误,或者我该如何解决它?
答:
您正在使用所谓的可变长度数组,但是存在问题。在 C 语言中,每个结构都必须具有特定的字节长度,以便可以进行计算。在您的例子中,可变长度数组的大小无法在编译时确定,因此这是非法的。sizeof(struct image)
另一方面,您可能希望在那里使用指针,而不是声明长度的数组:
typedef struct image
{
int width;
int height;
struct pixel **pixels;
};
免责声明:结构中的 VLA 偶尔是允许的,尽管此扩展是否更像是一个错误而不是一个功能,这是一个见仁见智的问题。请参阅:未记录的 GCC 扩展:结构中的 VLA
编辑:remyabel 指出了 GCC 文档,这些文档讨论了结构中 VLA 可以接受的罕见情况: https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html#Variable-Length
评论
我建议像这样选择:
typedef struct
{
int width;
int height;
struct pixel *pixels;
} image;
每次,您都需要分配:
image img;
/* init */
img.pixels=malloc(sizeof(struct pixel)*img.width*img.height);
*(img.pixels+img.height*i+j)
代表。img.pixels[i][j]
在 C99 及更高版本中,可以在结构的末尾有一个(一维)灵活数组成员 (FAM):
§6.7.2.1 结构和联合说明符
¶18 作为特殊情况,具有多个命名成员的结构的最后一个元素可能 数组类型不完整;这称为灵活数组成员。在大多数情况下, 灵活数组成员将被忽略。特别是,结构的大小好像 省略了灵活的数组成员,只是它可能具有比 省略意味着。但是,当 (或) 运算符的左操作数为 (指向)具有灵活数组成员的结构,并且右操作数名称为 member,它的行为就像该成员被替换为最长的数组(具有 元素类型),不会使结构大于被访问的对象;这 阵列的偏移量应保持灵活数组成员的偏移量,即使这会有所不同 从替换阵列的阵列。如果此数组没有元素,则其行为类似于 它有一个元素,但如果尝试访问该元素,则行为是未定义的 元素或生成一个指针。
.
->
这意味着你可以写:
typedef struct image
{
int width;
int height;
struct pixel pixels[];
} image;
但您必须自己进行 2D 到 1D 索引映射。您还必须注意如何分配结构(必须通过以下方式分配结构,否则数组的大小将为零)。malloc()
请注意为 添加一个名称(我选择匹配结构标签,但您可以选择您喜欢的任何其他名称)。没有名称的 A 是“有效的”,但没有用——你可以省略并得到相同的结果。typedef
image
typedef
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);
}
我不确定是否有一种好方法可以将 2D 数组作为 FAM。
上一个:浮点数学坏了吗?
评论