как array [100] = {0} устанавливает для всего массива значение 0?


140

Как компилятор заполняет значения char array[100] = {0};? Что за магия стоит за этим?

Я хотел знать, как инициализируется внутренний компилятор.


1
На C или C ++? Это два разных вопроса.
— Тоби Спейт

Ответы:


164

Это не волшебство.

Поведение этого кода на языке C описано в разделе 6.7.8.21 спецификации C ( онлайн-проект спецификации C ): для элементов, не имеющих указанного значения, компилятор инициализирует указатели на NULL, а арифметические типы - на ноль ( и рекурсивно применяет это к агрегатам).

Поведение этого кода в C ++ описано в разделе 8.5.1.7 спецификации C ++ ( онлайн-проект спецификации C ++ ): компилятор агрегатно инициализирует элементы, для которых нет указанного значения.

Также обратите внимание, что в C ++ (но не в C) вы можете использовать пустой список инициализаторов, заставляя компилятор агрегировать-инициализировать все элементы массива:

char array[100] = {};

Что касается того, какой код может сгенерировать компилятор, когда вы это сделаете, взгляните на этот вопрос: Странная сборка из нулевой инициализации массива


Все ли компиляторы C делают это? Меня заставили поверить, что это делает только Visual Studio.
— JFA

1
онлайн-черновик спецификаций c ++ сломан, у кого-нибудь есть новая ссылка?
— Behrooz Karjoo 02

35

Реализация зависит от разработчиков компилятора.

Если ваш вопрос - «что произойдет с таким объявлением» - компилятор установит для первого элемента массива значение, которое вы указали (0), а все остальные будут установлены в ноль, поскольку это значение по умолчанию для пропущенных элементов массива.


У меня нет источника, но я почти уверен, что где-то читал, что не существует значения по умолчанию для объявлений массивов; вы получаете тот мусор, который уже был там. Нет смысла тратить время на установку этих значений, если вы все равно можете их перезаписать.
— Райан Фокс,

10
Райан, если вы не установите значение для первого элемента, что весь массив не инициализирован и действительно содержит мусор, но если вы установите значение хотя бы для одного его элемента, весь массив станет инициализированным, поэтому неуказанные элементы инициализируются неявно, чтобы 0.
— qrdl

1
Для C ++ пустой список инициализаторов для ограниченного массива по умолчанию инициализирует все элементы.
— далле

2
@NatanYellin Где я сказал, что это не определено? Пожалуйста, прочтите полный ответ, прежде чем комментировать и голосовать против.
— qrdl 02

1
@qrdl Вы правы. Я неправильно понял ваш комментарий о реализации. К сожалению, сейчас я не могу изменить свой голос.
— Натан Йеллин

27

Если ваш компилятор - GCC, вы также можете использовать следующий синтаксис:

int array[256] = {[0 ... 255] = 0};

См. Http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html#Designated-Inits и обратите внимание, что это особенность компилятора .


Добро пожаловать! раз уж вы просили
— поискать

1
Вы, конечно, можете сделать это, если захотите, но есть очевидные недостатки в использовании таких специфичных для компилятора расширений, как это.
— Дэн Олсон,

@Dan Olson сам задает вопрос о компиляторе и, следовательно, опубликовал это. Если посчитаете, что это бесполезно, удалю.
— lakshmanaraj

5
Это не бесполезно, это интересно. Это предостережение заслуживает упоминания.
— Дэн Олсон,


19

Это зависит от того, где вы разместите эту инициализацию.

Если массив статический, как в

char array[100] = {0};

int main(void)
{
...
}

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

Если ваш массив автоматический, то это отдельная история.

int foo(void)
{
char array[100] = {0};
...
}

В этом случае при каждом вызове функции foo у вас будет скрытый memset.

Приведенный выше код эквивалентен

int foo(void)
{ 
char array[100];

memset(array, 0, sizeof(array));
....
}

и если вы опустите инициализатор, ваш массив будет содержать случайные данные (данные стека).

Если ваш локальный массив объявлен статическим, как в

int foo(void)
{ 
static char array[100] = {0};
...
}

то технически это тот же случай, что и первый.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.