[英]initializing array of pointers to structs
如何在不创建指向这些结构的指针列表的中间数组的情况下初始化结构的数组? 考虑以下示例代码:
snippets $ cat a2p.c
struct shape {
int angles;
char shape_name[16];
};
typedef struct shape shape_t;
struct container {
char name[32];
shape_t **elements;
int num_elts;
};
typedef struct container container_t;
shape_t triangle = {
.angles = 3,
.shape_name = {"Triangle"}
};
shape_t rectangle = {
.angles = 4,
.shape_name = {"Rectangle"}
};
container_t c = {
.name = {"Case"},
.elements = {
&triangle,
&rectangle
},
.num_elts =2
};
int main(void) {
return 0;
}
我需要.elements成员指向指向shape_t结构的指针数组,但是此代码无法编译:
snippets $ gcc -c a2p.c
a2p.c:24:2: warning: braces around scalar initializer
.elements = {
^
a2p.c:24:2: note: (near initialization for ‘c.elements’)
a2p.c:25:3: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
&triangle,
^
a2p.c:25:3: note: (near initialization for ‘c.elements’)
a2p.c:26:3: warning: excess elements in scalar initializer
&rectangle
^
a2p.c:26:3: note: (near initialization for ‘c.elements’)
snippets $
但是,如果我添加一个中间数组,如下所示:
shape_t *shapes[] = {
&triangle,
&rectangle
};
container_t c = {
.name = {"Case"},
.elements = shapes,
.num_elts =2
};
该代码可以编译。 我是否可以避免在中间步骤中创建shapes []数组,而直接使用所有数据(例如第一个代码段)直接初始化container_t? 那么正确的初始化语法是什么?
你快到了; 您只需要确保elements
初始值设定项是合适的指针,如下所示:
struct shape {
int angles;
char shape_name[16];
};
typedef struct shape shape_t;
struct container {
char name[32];
shape_t **elements;
int num_elts;
};
typedef struct container container_t;
shape_t triangle = {
.angles = 3,
.shape_name = { "Triangle" }
};
shape_t rectangle = {
.angles = 4,
.shape_name = { "Rectangle" }
};
container_t c = {
.name = { "Case" },
.elements = (shape_t *[]) {
&triangle,
&rectangle,
},
.num_elts = 2,
};
int main(void) {
return 0;
}
请注意,为shape_t
元素的指针数组使用了复合文字。
您必须完全像在第二个片段中一样进行操作。 一次初始化就可以完成全部操作的唯一方法(如原始代码中那样)是,如果将elements
声明为shape_t *
的数组,如shape_t *elements[10]
,但是您可能不希望有固定值大小数组在那里。
如果将元素成员移动到结构DEFINITION的END,则可以在C99和更高版本的编译器上使用以下内容:
container_t c2 = { .name = {"Case2"}, .num_elts =3, .elements = { &(shape_t){ 3, "Triangle" } , &(shape_t){ 4, "Rectangle" }, &(shape_t){ 2, "Line" } } };
可变大小成员必须是结构的最后一个成员。
我这一部分讨厌容易出错的地方,您可以通过使用NULL指针结束列表并删除num_elts来摆脱对手动设置元素计数的需求:
container_t c2 = { .name = {"Case2"}, .elements = { &(shape_t){ 3, "Triangle" } , &(shape_t){ 4, "Rectangle" }, &(shape_t){ 2, "Line" }, NULL } };
现在,您只需遍历列表,直到NULL == container_list->elements[n]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.