Что имеет смысл - строка 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 *" или должны подключаться к не-С++-библиотекам.