C Инициализация статического массива - насколько многословным я должен быть? - PullRequest
7 голосов
/ 30 августа 2009

Чтобы инициализировать массив int со всеми нулями, мне нужно использовать:

int foo[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

Или это сработает:

int foo[10] = {0};

Ответы [ 4 ]

27 голосов
/ 30 августа 2009

В C / C ++, если вы инициализируете только первый элемент массива известного размера значением, остаток будет заполнен нулями, поэтому:

int foo[10] = {0};

будет делать именно то, что вы хотите.

Это также работает для структур:

struct bar {
    int x;
    int y;
    char c;
} myBar = {0};

инициализирует всех членов до 0.

Стандарт (C99 - 6.7.8 / 12 - Инициализация) гласит:

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

В C грамматика требует, чтобы внутри фигурных скобок было хотя бы одно «выражение-присваивание». «Выражение присваивания» может представлять собой множество вещей, от константы или идентификатора до более сложных выражений. Однако пустая строка не квалифицируется как «выражение-присваивание», поэтому между скобками должно быть что-то.

В C ++ грамматика специально разрешает инициализатор '{}', поэтому следующее также будет инициализировать массив нулем:

int foo[10] = {};

Вероятно, также стоит отметить, что в C ++ записи, которые не имеют определенного значения инициализатора в списке инициализации, будут «инициализированы значением» или «инициализированы по умолчанию», что может отличаться от инициализации нулями в зависимости от что такое конструкторы для типа переменной и соответствует ли компилятор стандарту C ++ 98 или стандарту C ++ 03 (возможно, это единственное различие между C ++ 98 и C ++ 03). Вся ситуация со значением в сравнении с инициализацией по умолчанию довольно сложна, поэтому, если вам интересно, посмотрите этот ответ: Есть ли в скобках после имени типа разница с новым? .

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

18 голосов
/ 30 августа 2009
int foo[10] = {0};

Это очень хорошо :) 1002 *


Обратите внимание, что если вы делаете следующее:

int foo[10] = {1};

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

0 голосов
/ 30 августа 2009

Wow, C вроде бы просто, но даже после многих лет цитирования спецификации просто удивительно, как что-то новое может появиться.

Я только что посмотрел его в спецификации первого издания (ANSI / ISO 9899-1990) и, конечно же, задан остаток от автоагрегата (6.5.7) «Если их меньше ... инициализируется неявно. .. ".

Итак: что-нибудь неавтоматическое. Всегда 0 (или, как инициализировано), независимо от того, инициализировано или нет. Авто: полностью инициализируется, если вы вообще инициализируете какие-либо элементы, в противном случае не инициализируются.

0 голосов
/ 30 августа 2009

все элементы, не упомянутые в инициализаторе, будут инициализированы с нулевым значением этого типа, где это применимо.

So int foo [10] = {0}; хорошо, остальные элементы, не упомянутые также будут 0

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