2016-03-07 2 views
2

Если я определяю простой массив:Объявление extern 2D-массив в C?

int tableint[][2] = { 
     {1, 2}, 
     {2, 4}, 
     {3, 9}, 
     {4, 16}, 
     {5, 25} 
}; 

и код в тот же файл, как:

printf("Value = %d\n",sizeof(tableint)); 
printf("Value = %d\n",sizeof(tableint[0])); 
printf("Num of rows = %d\n",sizeof(tableint)/sizeof(tableint[0])); 

Выход такой, как ожидалось:

Value = 40 
Value = 8 
Num of rows = 5 

Но если я перееду то же самое 'tableint' 2D-файл в отдельном файле и сохранить вышеприведенные операторы печати в предыдущем основном файле, но просто добавьте extern следующим образом:

extern int tableint[][2]; 

Я получаю сообщение об ошибке в следующей строке:

printf("Value = %d\n",sizeof(tableint)); 

как: недопустимого применения 'SizeOf' неполного типа "ИНТ [] [2]

Я любопытный знать, почему он работал, когда 2D-массив находился в одном файле, а не когда я переместил его в другой файл?

И, ошибка становится решена, если я определяю EXTERN как:

extern int tableint[5][2]; 

Есть ли способ, где мне не нужно упоминать количество строк в ехЬегпе здесь?

ответ

4

Массив, объявленный таким образом - с объявлением [] - будет иметь полный тип, если и только если объявление содержит инициализатор. Без инициализатора тип является неполным.

Это ваша разница, которая заставила его работать в первом случае.

Если вам действительно нужно объявить его как extern, тогда у вас нет выбора, кроме как указать все размеры явно, если вам требуется эта техника sizeof для работы (или пока вы хотите увидеть размер массива как постоянное выражение).

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

+0

Есть другие варианты, например. 'extern tableint [] [2];' плюс некоторая функция, которая получает длину –

+0

@ M.M .: Да, если OP не возражает потерять способность видеть размер как * постоянное выражение *. – AnT

+0

Большое вам спасибо! –

3

Это связано с тем, что исходные файлы C обрабатываются как отдельные, отдельные единицы перевода , которые могут быть скомпилированы независимо друг от друга (например, с gcc -c ...). Информация, хранящаяся в каком-либо блоке, недоступна для другого, пока не будет достигнута фаза сцепления.

С учетом сказанного, спецификации ясно, что вы не можете взять sizeof оператора для неполного типа, как и N1570 6.5.3.4/1 SizeOf и операторов _Alignof говорит:

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

+0

Большое вам спасибо! –

Смежные вопросы