[英]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.