"struct a a1 = {0};" отличается от "struct a a2 = {5};" Зачем? - PullRequest
4 голосов
/ 05 января 2012

Если struct a a1 = {0}; инициализирует все элементы (разных типов) структуры равными нулю, то struct a a2 = {5}; должен инициализировать ее как 5 .. no?

#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.j и a2.k всегда гарантированно инициализироваться до 0 в течение a a2 = {5}; (или), если это undefined behavior

OTOH, почему я не вижу все элементы s2, инициализированные в 5. Как инициализация struct выполняется во время {0} и чем она отличается при использовании {5}?

Ответы [ 6 ]

10 голосов
/ 05 января 2012

Ссылка:

Стандарт C99 6.7.8.21

Если в списке, заключенном в фигурные скобки, меньше инициализаторов, чем элементов или членовагрегат или меньшее количество символов в строковом литерале, используемом для инициализации массива известного размера, чем количество элементов в массиве, остальная часть агрегата должна быть неявно инициализирована так же, как объекты, имеющие статическую продолжительность хранения.

[EDIT]

Статические объекты и неявная инициализация:

Длительность хранения объекта определяет время жизни объекта.
Существует 3 хранилищадлительности:
статические, автоматические и распределенные

переменные, объявленные вне всех блоков, и переменные, явно объявленные со спецификатором класса статического хранилища, имеют продолжительность статического хранилища .Статические переменные по умолчанию инициализируются компилятором в ноль.

Рассмотрим следующую программу:

#include<stdio.h>

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

    return 0;
}

В приведенной выше программе i имеет автоматическое сохранение и, поскольку он не инициализирован явным образомего значение равно Не определено .
В то время как j имеет статическую продолжительность хранения, и гарантированно будет инициализировано компилятором до 0.

8 голосов
/ 05 января 2012

Пропущенные значения всегда будут обнуляться, так как стандарт говорит об этом.Таким образом, у вас по существу

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

и

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

, что, конечно, отличается.

2 голосов
/ 05 января 2012

Это не работает для

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

struct x xobj = {5};
2 голосов
/ 05 января 2012

Нет. В C, если ваш список инициализаторов неполон, все отсутствующие индексы будут заполнены 0. Итак, это:

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

эффективно становится:

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

Вот почему он, похоже, работает с {0}, но не работает с {5}.

1 голос
/ 05 января 2012

Поведение абсолютно одинаковое в обоих случаях. Если инициализаторов меньше, чем элементов в агрегате, то остальные элементы инициализируются , как если бы они были объявлены static, что означает, что они будут инициализированы равными 0 или NULL.

Просто в первом случае явный инициализатор имеет то же значение, что и неявный инициализатор.

Если вы хотите инициализировать все элементы вашего агрегата чем-то, отличным от 0, то вам придется предоставить явный инициализатор для каждого из них, т.е.

a a2 = {5, 5, 5};
1 голос
/ 05 января 2012

Взгляните на Назначенные инициализаторы в документации GCC.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...