Разница между символом и символом [1] - PullRequest
55 голосов
/ 08 ноября 2010

В C ++, в чем разница (если есть) между использованием char и char [1].

Примеры:

struct SomeStruct
{
   char x;
   char y[1];
};

Следуют ли те же причины для неподписанного символа?

Ответы [ 3 ]

39 голосов
/ 08 ноября 2010

Основным отличием является только синтаксис, который вы используете для доступа к вашему одному символу.

Под «доступом» я имею в виду, действуя по нему, используя различные операторы в языке, большинство или все из которых выполняют разные действияпри применении к char по сравнению с массивом char.Это звучит так, как будто x и y почти полностью отличаются.Если факт, что они оба «состоят» из одного символа, но этот символ был представлен совсем по-другому.

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

Пример различий в операторах заключается в том, что символ можно назначить, а массив - нет:

SomeStruct a;
a.x = 'a';
a.y[0] = 'a';
SomeStruct b;
b.x = a.x; // OK
b.y = a.y; // not OK
b.y[0] = a.y[0]; // OK

Но тот факт, что y isn 't назначаемый не останавливает SomeStruct назначаемый:

b = a; // OK

Все это независимо от типа, char или нет.Объект типа и массив этого типа с размером 1 во многом совпадают с тем, что находится в памяти.

Кроме того, существует контекст, в котором он имеет большое значение, котороевы «используете» из char и char[1], и это иногда помогает сбить людей с толку думать, что массивы действительно указатели.Не ваш пример, а как параметр функции:

void foo(char c);     // a function which takes a char as a parameter
void bar(char c[1]);  // a function which takes a char* as a parameter
void baz(char c[12]); // also a function which takes a char* as a parameter

Числа, указанные в объявлениях bar и baz, полностью игнорируются языком C ++.Очевидно, кто-то в какой-то момент почувствовал, что это было бы полезно для программистов как форма документации, указывающая, что функция baz ожидает, что ее аргумент-указатель укажет на первый элемент массива из 12 символов.

В барах и базах c никогда не имеет типа массива - это похоже на тип массива, но это не так, это просто причудливый синтаксис особого случая с тем же значением, что и char *c.Вот почему я поставил кавычки на «использование» - вы на самом деле не используете char[1], просто это выглядит так.

11 голосов
/ 08 ноября 2010

Если вы действительно видели конструкцию char y[1] как последний элемент структуры в производственном коде, то вполне вероятно, что вы столкнулись с экземпляром struct hack .

Этот короткий массив является заменой для реального массива переменной длины (напомним, что до c99 в стандарте c такого не было). Программист всегда размещал такие структуры в куче, заботясь о том, чтобы распределение было достаточно большим для фактического размера массива, который он хотел использовать.

3 голосов
/ 08 ноября 2010

Помимо нотационных различий в использовании, подчеркнутых Стивом, char [1] может быть передан, например, template <int N> void f(char(&a)[N]), где char x = '\0'; f(&x); не будет соответствовать.Надежный захват размера аргументов массива очень удобен и обнадеживает.

Это также может означать нечто иное: либо реальная длина может быть больше (как объяснено dmckee), либо что содержимое логически является строкой ASCIIZ.(в данном случае это будет пустой) или массив символов (который имеет один элемент).Если структура была одной из нескольких связанных структур (например, математическим вектором, где размер массива был аргументом шаблона, или кодировкой расположения памяти, необходимой для некоторой операции ввода / вывода), то вполне возможно, что некоторое сходство с другими полямиесли массивы могут быть больше, это будет означать предпочтение односимвольному массиву, что позволит вспомогательному коду быть проще и / или более универсально применимым.

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