Во-первых, обратите внимание на языковую разницу между инициализацией и назначением .Первое происходит, когда переменной присваивается значение одновременно с объявлением, а второе - все, что дает переменной значение во время выполнения.Если вы устанавливаете все элементы переменной в цикле, вы делаете это во время выполнения, и поэтому присваивает массиву значений.
{} называется списком инициализатора.Списки инициализатора могут только находиться в той же строке, что и объявление переменной, и все элементы в списке должны быть константами (при условии стандарта C90).Они могут использоваться для инициализации обоих массивов или структур (также называемых «агрегатами»), к обоим применяются одни и те же правила.
int arr [5] = {0};
Что это делает подробно, должен установить первый элемент с индексом [0] на ноль.Остальные выпуски инициализируются в соответствии с правилом, которое гласит, что если в списке инициализатора задано только несколько элементов, то элементы, которые не были явно инициализированы программистом, должны быть установлены в ноль компилятором (ISO 9899: 1999 6.7.8 §19).
Таким образом, приведенная выше строка устанавливает arr [0] в ноль, а затем компилятор устанавливает остальные элементы, arr [1] в arr [4], в ноль.Если бы вы написали
int arr [5] = {1};
, тогда элементы массива были бы инициализированы в {1, 0, 0, 0, 0}.