Подтвердить что ты не робот

Разница между char и char [1]

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

примеры:

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

Выполните те же самые причины для unsigned char?

4b9b3361

Ответ 1

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

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

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

Примером различий оператора является то, что a char можно присваивать, а массив не равен:

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 не присваивается, не останавливает 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, полностью игнорируются языком С++. По-видимому, кто-то в какой-то момент считал, что программистам будет полезно как форма документации, указывая, что функция baz ожидает, что ее аргумент указателя указывает на первый элемент массива из 12 char.

В bar и baz c никогда не имеет типа массива - он выглядит как тип массива, но это не так, это просто причудливый синтаксис специального случая с тем же значением, что и char *c. Вот почему я помещал кавычки в "use" - вы вообще не используете char[1], он просто выглядит.

Ответ 2

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

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

Ответ 3

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

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