Что имеет смысл - строка char * или char *?

Возможный дубликат:
В C, почему звездочка перед именем переменной, а не после типа?

Я изучаю С++ на данный момент, и я сталкиваюсь с множеством строк с нулевым завершением. Это заставило меня задуматься, что имеет смысл при объявлении указателей:

char* string

или

char *string

? Для меня формат char * имеет больше смысла, потому что тип "строка" является указателем на char, а не на char. Тем не менее, я обычно вижу последний формат. Это также относится и к ссылкам.

Может ли кто-нибудь сказать мне, есть ли логическая причина для последнего формата?

Ответ 1

В следующем объявлении:

char* string1, string2;

string1 является символьным указателем, но string2 является единственным символом. По этой причине декларация обычно форматируется следующим образом:

char *string1, string2;

что делает его несколько яснее, чем * применяется к string1, но не string2. Хорошая практика заключается в том, чтобы избежать объявления нескольких переменных в одном объявлении, особенно если некоторые из них являются указателями.

Ответ 2

Bjarne Stroustrup что-то сказать об этом:

Критическая путаница приходит (только), когда люди пытаются объявить несколько указателей с одним объявлением:

int* p, p1; // probable error: p1 is not an int*

Ответ 3

Технически, имеет смысл написать

char *f

Потому что *f является декларатором в этом, а char - спецификатором объявления, который указывает базовый тип всех деклараторов. Декларации содержат такие операторы, как (), [] и &, которые можно рассматривать как модификацию базового типа и фактического идентификатора.

Я использую приведенную выше форму ввода * в идентификатор, потому что он подчеркивает, что *f фактически является объявлением, а char является основным типом.

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

int a, *b, &c = a, d(), e[1], C::*f;

Обратите внимание, что все a, *b, d() и e[1] статически разрешают int, кроме &c и C::*, которые объявляют ссылку (поэтому ее необходимо инициализировать) и указатель на элемент класса соответственно.

Ответ 4

То, о чем еще никто не сказал, состоит в следующем:

char *string

также может быть прочитан как объявление типа выражения *string (чтение: оператор косвенности, примененный к указателю string) как char. С этой точки зрения обозначения вполне разумны.

При этом я использую

char * string

сам;)

Ответ 5

(std::string лучше, чем char * для большинства целей.)

Я всегда ставил * с типом, как в char *, потому что как отметил Stroustrup, это подчеркивает тип.

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

char* p, q;  // oops, probably not what was meant
// this is mandated by our style guide:
char* p;
char* q;

Ответ 6

В С++ имеет смысл помещать * в идентификатор типа, например char *, поскольку он является частью самого типа.

Но если вы определяете несколько переменных в одном и том же выражении, это становится неоднозначным и вводящим в заблуждение.

char* foo, bar;

В то время как foo имеет тип char *, bar имеет тип char. Поэтому многие предпочитают

char *foo, bar;

чтобы это стало ясно.

Ответ 7

В большинстве случаев std::string str гораздо предпочтительнее char *.

При этом я обычно делаю что-то вроде DataType * ptr, чтобы сделать * лучше. Или, гораздо чаще, std::tr1::smart_ptr<DataType> ptr, или, возможно, auto_ptr.

Очень просто, необработанные указатели опасны для использования довольно многими способами, и если я собираюсь использовать их, я хочу, чтобы он выделялся.

Ответ 8

Мне очень нравится идиома "char* foo", потому что она помещает всю информацию о типе переменной в одном месте. "char *foo" может быть довольно запутанным, если часть "*foo" находится на полке по экрану!

С другой стороны, я согласен с другими плакатами, что это запутывает при объявлении нескольких переменных в одной строке. Я стараюсь не смешивать типы при объявлении нескольких переменных в одной строке, а char и char* - это отдельные типы, поэтому конкретная ситуация не такая, которая могла бы произойти в моем коде.

Ответ 9

Мой ответ: нет, вы должны использовать:

char * string;

Учтите, что если Деннис Ритчи (разработчик языка C) вместо использования символа '*' использовал ключевое слово 'ptr', мы все должны были бы сказать:

char ptr string;

и не имея этих обсуждений.

Это также ИМХО, более читаемый.

Ответ 10

учитывая, что вы можете сделать несколько деклараций в одной строке, мне кажется более разумным, что она принадлежит переменной, а не типу, например

char *pString, arrString[20];

Ответ 11

Я тоже думаю, что char * foo имеет смысл при объявлении одной переменной.

Единственный раз, когда я использую другой формат, является объявление нескольких переменных в одной строке, например:

char * foo, bar;

Ответ 12

Лично я никогда не объявляю несколько переменных в одной строке.

Из-за этого и того факта, что я действительно нахожу шаблоны приятными, я нахожу этот простой шаблон привлекательным:

type varname

Это означает, что я почти всегда говорю int [] iArray или int * piArray (или независимо от венгерской нотации, я не использовал С++ в течение десятилетия).

Это также означает, что я никогда не использую int iArray [], поскольку тот факт, что он является массивом, является типом, а не именем переменной.

Мышление таким образом помогло мне упростить определения несколько раз.

Просто предлагая другой POV

Ответ 13

Первое предложение (из char * var) будет прекрасным, пока вы объявляете только одну переменную в строке, но лично я предпочитаю "char * var;" и одну переменную в строке - это может сделать функцию более длинной в подсчете строк, но очень ясна.

Наконец, С++ должен использовать "string var", но мы всегда наследуем код "char *" или должны подключаться к не-С++-библиотекам.