, что будет размерность массива целых чисел обр, если объявлен как это:Декларация массива без самой высокой размерности
int arr[][2]={1,2,3};
что использование не объявляя самый высокий размер?
, что будет размерность массива целых чисел обр, если объявлен как это:Декларация массива без самой высокой размерности
int arr[][2]={1,2,3};
что использование не объявляя самый высокий размер?
Несколько к моему удивлению, ваше заявление:
int arr[][2]={1,2,3};
, как представляется законным. Вы можете юридически опустить внутренние фигурные скобки в инициализаторах. Например, если вы хотите, чтобы определить границы arr
явно и инициализировать все ее элементы, можно написать либо:
int arr[2][2] = { { 1, 2}, { 3, 4 } };
или, что то же самое:
int arr[2][2] = { 1, 2, 3, 4 };
Вы также можете опустить конечные элементы и они будут неявно установлены на ноль. Для одномерного массива это прямолинейно; это:
int arr[4] = { 1, 2, 3 };
эквивалентно:
int arr[4] = { 1, 2, 3, 0 };
И если опустить измерение, оно может быть выведено из инициализаторе:
int arr[] = { 1, 2, 3, 4 }; // 4 elements
Поскольку вы определяете arr
как массив из 2-элементных массивов int
, это:
int arr[][2]={1,2,3};
эквивалентно следующему:
int arr[][2] = { { 1, 2 }, { 3 } };
У вас есть два элемента в инициализаторе (каждый из которых инициализируется массив 2-элемент), так что это эквивалентно:
int arr[2][2] = { { 1, 2 }, { 3 } };
Наконец, вы» ве опущен последней инициализации подэлемент, так что это неявно нулю:
int arr[2][2] = { { 1, 2 }, { 3, 0 } };
В общем, опуская размеры и конечные инициализаторы I полезно, потому что он позволяет компилятору выяснить некоторые вещи. Если я пишу:
char message[] = "hello, world";
Я не должен считать символы в строке (и добавить 1 для завершающего '\0'
). Компьютеры действительно хороши в подсчете вещей; заставляя человека делать эту работу глупо.
Аналогичным образом, опускание некоторых инициализаторов позволяет предоставить только необходимую информацию. С добавлением C99 в назначенных инициализаторах, вы можете даже инициализировать указанный элемент структуры и пусть компилятор позаботится обо всем остальном:
struct foo obj = { .something = 42 };
As для выпрямления инициализаторов опуская внутренние фигурные скобки, я лично не вижу для этого используется много, за исключением специального случая использования инициализатора { 0 }
для инициализации и полного массива или структуры до нуля.В частности, для многомерных массивов я нашел много clearer, чтобы показать всю структуру массива.
Не правда. Последний элемент - хлам, в соответствии с gcc и g ++. – Jiminion
@ Jim: У вас есть цитата для этого? В стандарте ISO C указано, что «все подобъекты, которые не инициализированы явно, должны быть инициализированы неявно так же, как и объекты , имеющие статическую продолжительность хранения», то есть до нуля. (Если нет инициализатора вообще, и объект определен в области блока, начальное значение - мусор.) –
Ну, я построил рутину и протестировал ее. Это цитата? – Jiminion
согласно минимального брекетинга правила (6.7.9p20 в С11),
достаточно Инициализаторов из списка принимаются для учета элементов или членов subaggregate или первого члена содержащемуся союза ; любые оставшиеся инициализаторы оставляют для инициализации следующего элемента или члена совокупности, частью которого является текущий субагрегат или содержащий объединение.
Итак следующие объявления эквивалентны:
int arr[][2]={1,2,3};
int arr[][2]={{1,2},{3}};
int arr[2][2]={{1,2},{3}};
Как, почему это полезно: при инициализации большого многомерного массива, она вполне может быть очевидной для читателя, сколько элементов есть в subaggregate; в этом случае нет необходимости поставлять скобки между суммирующими элементами.
Гибкость. Компилятор определяет размер в самом измерении, поэтому, если вы добавляете больше элементов, вам не нужно изменять константу в объявлении. (Но компилируется?) –
Да (g ++, и gcc) – Jiminion