Внешнее Delaration для Массива? - PullRequest
24 голосов
/ 18 июня 2010

У меня есть массив, определенный в файле, и в другом я должен использовать его, например, -

/* a.c - defines an array */

int a[] = {1,2,3,4,5,6,7,8,9}; 


/* b.c - declare and use it. */

#define COUNT ((sizeof a)/(sizeof int))
extern int a[];  //size of array

.
.
.

int i;
for(i=0; i<COUNT; i++)
  printf("%d", a[i]);
.
.
.

Теперь, когда я пытаюсь его скомпилировать, он выдал ошибку, говорящую, что sizeof не можетиспользуется для неполного типа.

Кто-нибудь может сказать мне, как обрабатывать такие случаи в C / C ++?Я не хочу массив индексировать в AC

Заранее спасибо

Ответы [ 6 ]

24 голосов
/ 18 июня 2010

Вы можете поместить что-то вроде следующего в a.c, а затем удалить его из b.c.

В переменном токе:

int a[] = {1, 2, 3};
const int lengthofa = sizeof( a ) / sizeof( a[0] );

А затем в БК:

extern int a[];
// the extern (thanks Tim Post) declaration means the actual storage is in another 
// module and fixed up at link time.  The const (thanks Jens Gustedt) prevents it
// from being modified at runtime (and thus rendering it incorrect).
extern const int lengthofa;

void somefunc() {
  int i;
  for ( i = 0; i < lengthofa; i++ )
    printf( "%d\n", a[i] );
}
16 голосов
/ 18 июня 2010

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

extern int a[9];

Inв этом случае ваша ответственность состоит в том, чтобы убедиться, что размер массива согласован между объявлением и определением extern.Для этого вы можете использовать константу манифеста, но все равно вы должны будете убедиться, что число инициализаторов между {} и объявленным размером одинаково.

Если вы этого не сделаетеесли вы хотите, чтобы размер массива был постоянной времени компиляции, тогда вы можете делать то, что предлагает Марк Уилкинс в своем ответе.

1 голос
/ 25 марта 2015

Я бы #define ARRAY_MAX (or whatever) во внешнем заголовке, обычно используемом для определения таких вещей, затем включил бы этот заголовок в оба файла, в которых он необходим. Это хорошо работает, когда вы склонны хранить большинство, если не все свои define в одном или двух центральных заголовках.

1 голос
/ 18 июня 2010

Компилятору не хватает информации при компиляции b.c, чтобы определить размер массива. Эта информация находится только в .c, где ваш список инициализатора находится в области видимости.

Вам нужно будет как-то сообщить размер. Один из методов - определить int const с размером и внешним значением. Другой возможностью было бы использовать часовой (значение вне вашего допустимого диапазона данных), чтобы указать конец массива.

0 голосов
/ 15 декабря 2018

Поместите переменную в заголовочный файл только так:

#ifndef A_DEF
#define A_DEF
int a[] = {1,2,3,4,5,6,7,8,9}; 
#endif

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

0 голосов
/ 18 июня 2010

по моему мнению, если у вас нет определения и определения с размером a в одном файле, он не компилируется.

Файлы компилируются и хранятся как * .obj / * .a файлы.Вы можете использовать массивы из других файлов благодаря объявлению extern, которое будет проверяться в процессе компоновки после компиляции.

Вы хотите объявить define (здесь должен помочь препроцессор. Он запускается до компилятора).

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

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