2013-05-01 3 views
1

У меня есть следующая программа в двух файлахПроблемы доступ к внешнему поплавку массиву

main.cpp

float POW10[300]; 
    main(0 
    { 
     Fill_POW10(); 
    } 

Fill.cpp

extern float *POW10; 
Fill_POW10() 
{ 
    for(int i=0;i<300;i++) 
    { 
    POW10[i]=i; 
    } 
} 

Это разбилось с ошибкой сегментации. Когда я проверяю, POW10 имеет значение NULL. Однако если я изменю Fill.cpp на

extern float POW10[]; 
Fill_POW10() 
{ 
    for(int i=0;i<300;i++) 
    { 
    POW10[i]=i; 
    } 
} 

код работает нормально. Я думал, что POW10 фактически реализован как указатель на поплавки, и поэтому коды должны быть идентичными. Не могли бы вы объяснить, почему это не так.

ответ

1

Сначала прочитайте эту запись, которая объясняет проблему:

http://c-faq.com/aryptr/aryptr1.html

Тогда прочтите это следить за который объясняет различия между массивом и указателем.

http://c-faq.com/aryptr/aryptr2.html

+0

Спасибо большое .. Я получаю полную картину сейчас. – drcyber

3

Массивы и указатели - совершенно разные типы. Когда вы определяете переменную указателя, все, что вы получаете, это единственный указатель, который может или не может на самом деле указывать в любом месте. Когда вы определяете массив, вы получаете непрерывную последовательность объектов.

Возможно, вы думаете о типах аргументов функции, где типы массивов преобразуются в типы указателей. То есть void foo(int arg[]) эквивалентен void foo(int* arg). Это справедливо только для аргументов функции.

1

Тип POW10 - это массив из 300 float. Это не Указатель на float. Когда вы меняете свое объявление extern в соответствии с определением, проблема исчезает.

0

Потому что компоновщик не разрешает ваше объявление float * POW10 в определении поплавка POW10 [], но фактически создает отдельное определение в целом, которое заканчивается неинициализацией (NULL, как вы это переживали).

+1

Компоновщик видит только имя, так что ** ** ли разрешить Экстерн ссылку на определение. Вот почему код выходит из строя: декларация extern имеет неправильный тип, поэтому код, который генерирует компилятор для доступа к POW10 через декларацию extern, не имеет доступа к нему правильно. Формально поведение здесь не определено. –

+0

@PeteBecker Да, спасибо за разъяснение –