Не могу понять причину выхода? [Дубликат]

prasoon спросил: 28 марта 2018 в 03:54 в: c

У этого вопроса уже есть ответ:

  • Why is this array having all remaining values initialized to zero? 4 ответа
  • Does a string literal count as a partial initializer and zero-initialize? 3 ответа
//Language C
int main()
{
    int a[5]={0};
    for(int i=0 ; i < 4 ; i++ )
        printf("%d",a[i]);
    }
}

Вывод следующего списка: 1000 в gcc. Но я думал, что он должен печатать 1 и сохранять значения мусора, поскольку я не присваивал значения другим местоположениям массива.

Если версия компилятора не принимается во внимание, правильно ли я думаю? Или я чего-то не хватает.

1 ответ

Есть решение
Felix Palmen ответил: 28 марта 2018 в 04:04

Стандарт C (цитирующий последний проект C11 N1570 здесь) объясняет это довольно хорошо.

§6.7.9 Инициализация, p21:

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

(выделено мной)

, поэтому каждый элемент, кроме a[0] в вашем коде инициализируется неявно . Теперь давайте посмотрим, что это значит:

§6.7.9 Инициализация, p10:

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

(снова выделение мое)

поэтому a[1] в a[4] инициализируется в 0 - тип int является арифметический тип .

prasoon ответил: 28 марта 2018 в 04:10
Спасибо за ясность.
Felix Palmen ответил: 28 марта 2018 в 04:15
@Prasoon, пожалуйста. Поначалу стандарт C может быть немного сложен для чтения, но это окончательный справочник :) Кстати, если ваше предположение было бы правильным, ваша программа была бы "неопределенной" - вы Вы не можете использовать неинициализированные значения, и ваша программа может делать "что угодно", если вы делаете ...
prasoon ответил: 28 марта 2018 в 04:21
Я попытаюсь прочитать стандарт C, хотя использование большого количества стандартных терминов делает его таким сложным. Еще раз спасибо.