В чем разница между этими внешними объявлениями в C ++? - PullRequest
0 голосов
/ 18 декабря 2011

Позволяет получить файлы со следующим содержимым:

file1.cpp: double array[100];

file2.cpp (клиент file1.cpp):

/// What the difference between this:
extern double* array;

/// and this?
extern double array[];

Если я использую массив, объявленный первым способом, я получаю segfault. Если второе, все работает нормально. Это смущает меня, так как в обычной программе на C ++ я легко могу сделать следующее, и эти объекты будут равны:

double array[100];
double* same_array = array;

/// array[0] is equal to same_array[0] here
/// But why they are not equal in the example with extern?

Ответы [ 2 ]

2 голосов
/ 18 декабря 2011
extern double* array;

Когда вы сейчас делаете array[i], и в каком-то месте array на самом деле определяется как массив (а не как указатель, как указано выше), тогда он попытается интерпретировать содержимое массив как адрес. Так, например, в другом файле / другой единице перевода, которую мы определили как

double array[1] = { 0.0 };

Предположим, что 0.0 имеет все биты ноль. Тогда операция array[1] над extern double*, приведенной выше, будет пытаться разыменовать адрес указателя, имеющий все биты ноль. На большинстве коробок это будет сбой. А по остальным другим это приведет к случайной чепухе.

2 голосов
/ 18 декабря 2011

Разница в том, что сначала указатель на тип double
а второй массив двойных.

Важно отметить следующее:

Массивы не являются указателями!

Выражение с типом массива (которое может быть именем массива) преобразует в указатель всякий раз, когда тип массива недопустим, но тип указателя является.

double array[100];
double* same_array = array;

Согласно упомянутому правилу, в приведенном выше имени массива происходит переход к указателю на его первый элемент.

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

Это должно быть хорошее чтение:
Как использовать массивы в C ++?

...