Объявление строки C и массива char - PullRequest
1 голос
/ 30 января 2012

Учитывая, что это разрешено:

char c[] = "abc";
char c[] = {'a','b','c','\0'}
char *c = "abc";

Почему же это запрещено?

char *c = {'a','b','c','\0'};  // error: a char cannot initialize a char*

Если строковый литерал интерпретируется компилятором как завершенный нулем массив символов, то я бы подумал, что это эквивалентно приведенному выше утверждению 3, не так ли?

Аналогично, почему это не разрешено:

int arr[3];
int *i = arr; // OK
int *i = {1,2,3} // error: an int cannot initialize an int*

Это не огромная проблема, мне просто любопытно ... Думаю, вопрос сводится к тому, в чем разница между строковым литералом (или объявленным целочисленным массивом) и массивом символьных элементов при назначении указателя?

Ответы [ 3 ]

9 голосов
/ 30 января 2012

Массивы не указатели. Инициализация массива символов строковым литералом - это особый случай (6.7.8 # 14):

Массив символьного типа может быть инициализирован литералом символьной строки, необязательно заключенным в фигурные скобки. Последовательные символы литерала символьной строки (включая завершающий нулевой символ, если есть место или массив имеет неизвестный размер) инициализируют элементы массива.

, а также (6.7.8 # 16):

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

Что касается инициализации указателя (6.7.8 # 11):

Инициализатор для скаляра должен быть одним выражением, необязательно заключенным в фигурные скобки. Начальное значение объекта - это значение выражения (после преобразования); применяются те же ограничения и преобразования типов, что и для простого присваивания, принимая тип скаляра за неквалифицированную версию объявленного им типа.

0 голосов
/ 31 января 2012

Массивы не указатели. Просто имя массива является указателем на 1-й элемент массива.

То, что вы спрашиваете здесь, - это другой метод инициализации массива в C / C ++. Пожалуйста, обратите внимание:

  1. Массивы могут быть инициализированы только в строке объявления
  2. В C / C ++ нет типа String
  3. Массив символов используется как строка в C / C ++.
  4. Инициализация массива символов имеет то же правило, что и для других массивов.
  5. Если мы определим массив без явной длины, он будет определен с длиной числа начальных значений.
  6. Если вы не определите начальное значение, элементы будут неопределенными. Это означает, что значение элемента массива изначально неясно.
  7. если у вас есть массив и назначено начальное значение для 1-го из нескольких элементов, остальные элементы будут равны 0.
  8. Я дополню этот список позже; -)
0 голосов
/ 30 января 2012

Строковый литерал - это особый случай неназванных данных в section DATA. С массивами вы должны вручную выделить место в куче и переместить туда данные. (По одному, поскольку вы не можете назначать массивы.)

...