使用数组元素初始化结构体数组

3
#include <stdio.h>

int main()
{
    typedef struct s
    {
        int a;
        int b[5];
        char c[2];
    }st;

    st vs[1];

    vs[0] = {1,{1,2,3,4,5},{'c','d'}};

    printf("%d:a\n",vs[1].a);
    printf("%d:b[0]\t %d:b[4]\n",vs[0].b[0],vs[0].b[4]);
    printf("%c:c[0]\t %c:c[1]\n",vs[0].c[0],vs[0].c[1]);

    return 0;
}

为什么这个不起作用?

gcc -o main *.c 

我遇到了这个错误:

main.c: 在函数'main'中: main.c:15:12: 错误:在‘{’标记之前应有表达式 vs[0] ={1,{1,2,3,4,5},{'c','d'}};

但如果我使用以下代码:

#include <stdio.h>

int main()
{
    typedef struct s
    {
        int a;
        int b[5];
        char c[2];
    }st;

    st vs[] = {
                {1,{1,2,3,4,5},{'c','d'}}
              };

    printf("%d:a\n",vs[0].a);
    printf("%d:b[0]\t %d:b[4]\n",vs[0].b[0],vs[0].b[4]);
    printf("%c:c[0]\t %c:c[1]\n",vs[0].c[0],vs[0].c[1]);

    return 0;
}

它有用。这其中的逻辑是什么。

如何使用st vs[1]方法使其工作?

2个回答

8

只有在声明变量时才能使用大括号初始化。所以,

st vs[] = {
            {1,{1,2,3,4,5},{'c','d'}}
          };

被允许。但是

vs[0] = {1,{1,2,3,4,5},{'c','d'}};

这并不是初始化而是赋值。但是,你可以使用C99的复合字面量,参见C11, 6.5.2.5
vs[0] = (struct s){1,{1,2,3,4,5},{'c','d'}};

3

初始化是在声明变量时提供初始值的过程。例如,以下代码是合法的:

st vs[1] = { {1,{1,2,3,4,5},{'c','d'}} };

您的代码实际上正在尝试赋值。 赋值是指将一个现有变量分配给一个值。 您的代码无法正常工作的原因是{1,{1,2,3,4,5},{'c','d'}} 不是一个值。

在语句(而不是声明)中,每个表达式必须能够独立地被编译器读取,并且更复杂的语句由各种由运算符连接的表达式组成。 因此,编译器不知道如何处理{1,{1,2,3,4,5},{'c','d'}} - 在这个阶段,它根本不知道那应该是一个st

自C99以来,有一个新的语言结构可以在此处使用,称为复合字面值

vs[0] = (const st){1,{1,2,3,4,5},{'c','d'}};

请注意,这不是将某种括号表达式应用于转换运算符;它是一个单一的语法结构(Typename){initializers}
我使用const是一种微观优化,它可能帮助编译器将文字存储在可执行文件的只读块中,并允许常量折叠。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接