初始化结构的指针数组

时间:2016-09-23 23:59:00

标签: c

如何在不创建指向这些结构的指针列表的中间数组的情况下初始化结构数组?请考虑以下示例代码:

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 sturcts的指针数组,但是这段代码不能编译:

 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吗?那么正确的初始化语法是什么?

3 个答案:

答案 0 :(得分:2)

你快到了;你只需要确保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元素的指针数组。

答案 1 :(得分:1)

你必须像在第二个片段中那样完成它。如果您将elements声明为shape_t *的数组,就像在shape_t *elements[10]中一样,那么您可以在一次初始化中完成所有操作的唯一方法就是{{1}},但您可能不会# 39;我想在那里有一个固定大小的数组。

答案 2 :(得分:1)

如果将元素成员移动到结构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]