" struct a a1 = {0};"不同于" struct a a2 = {5};"为什么?

时间:2012-01-05 15:55:46

标签: c struct

如果struct a a1 = {0};将结构的所有元素(不同类型)初始化为零,那么struct a a2 = {5};应将其初始化为5 ..否?

#include <stdio.h>

typedef struct _a {
    int i;
    int j;
    int k;
}a;

int main(void)
{
    a a0;
    a a1 = {0};
    a a2 = {5};

    printf("a0.i = %d \n", a0.i);
    printf("a0.j = %d \n", a0.j);
    printf("a0.k = %d \n", a0.k);

    printf("a1.i = %d \n", a1.i);
    printf("a1.j = %d \n", a1.j);
    printf("a1.k = %d \n", a1.k);

    printf("a2.i = %d \n", a2.i);
    printf("a2.j = %d \n", a2.j);
    printf("a2.k = %d \n", a2.k);

    return 0;
}

未初始化的结构包含垃圾值

a0.i = 134513937
a0.j = 134513456
a0.k = 0 

初始化为0结构包含初始化为0

的所有元素
a1.i = 0 
a1.j = 0 
a1.k = 0 

初始化为5结构只包含初始化为5的第一个元素,其余元素初始化为0

a2.i = 5 
a2.j = 0 
a2.k = 0

a2.ja2.k始终保证在0(或)期间初始化为a a2 = {5};undefined behavior

OTOH,为什么我没有看到s2初始化为5的所有元素。如何在struct期间完成{0}初始化,以及在使用{5}时它有何不同?

6 个答案:

答案 0 :(得分:10)

参考:

C99标准6.7.8.21

  

如果括号括起的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小的数组的字符串文字中的字符数少于数组中的元素,则剩余的聚合应隐式初始化,与具有静态存储持续时间的对象相同。

[编辑]

静态对象和隐式初始化:

对象的存储持续时间决定了对象的生命周期 有3个存储持续时间:
静态,自动和分配

在所有块之外声明的变量和使用静态存储类说明符显式声明的变量具有 static storage duration 。默认情况下,编译器将静态变量初始化为零。

考虑以下计划:

#include<stdio.h>

int main()
{
    int i;
    static int j;
    printf("i = [%d]",i);
    printf("j = [%d]",j);

    return 0;
}

在上述程序中,i具有自动存储功能,因为未显式初始化,其值为未定义
虽然j具有静态存储持续时间,但保证由编译器初始化为0

答案 1 :(得分:8)

省略的值将始终初始化为零,因为标准是这样说的。所以你基本上

struct a a1 = { 0, 0, 0 };

struct a a2 = { 5, 0, 0 };

当然不同。

答案 2 :(得分:2)

没有。在C中,如果您的初始化列表不完整,则所有缺失的索引都将填充为0.所以:

int a[3] = {0};
int b[3] = {5};

有效地成为:

int a[3] = {0, 0, 0};
int b[3] = {5, 0, 0};

这就是为什么它似乎适用于{0},但却失败了{5}

答案 3 :(得分:2)

它不适用于

struct x {
    int *y;
    /* ... */
};

struct x xobj = {5};

答案 4 :(得分:1)

在GCC文档中查看Designated Initializers

答案 5 :(得分:1)

两种情况下的行为完全相同。如果初始化器的数量少于聚合中的元素,则剩余的元素将被初始化,就像它们被声明为static一样,这意味着它们将被初始化为0或NULL。

只是在第一种情况下,显式初始值设定项与隐式初始值设定项具有相同的值。

如果要将聚合的所有元素初始化为0以外的其他元素,则必须为每个元素提供一个显式初始化器,即:

a a2 = {5, 5, 5};