Почему думают, что "T * name" - это путь C, а "T * name" - путь С++?
Примечание. Этот вопрос касается положения звездочки (*
).
В большинстве C-кода я вижу (например, в Beej guide для сетевого программирования), все объявления/определения переменных используют формат T *name
, т.е. привязать *
к имени переменной. Указатель считается принадлежностью к переменной, а не типу.
В большинстве кодов С++ я вижу, что формат T* name
, т.е. привязывает *
к типу переменной. Указатель считается принадлежностью к типу, а не переменной. Я сам, как чистый С++-кодер, также использую этот формат, так как явный указатель на тип (для меня) принадлежит типу, а не переменной. (Кстати, даже стандарт С++ использует этот формат в примерах.:))
Есть ли (историческая) причина для этого? Изменился ли образ мышления, когда программисты начали делать С++?
Было бы неплохо, если бы C-кодер (использующий прежний формат) мог бы объяснить, почему он/она использует его, а не последний.
Ответы
Ответ 1
Из Часто задаваемые вопросы по стилю и технике Stroustrup С++.
"Типичный C-программист" пишет int *p;
и объясняет это "*p
- это синтаксис подчеркивания int
" и может указывать на грамматику декларации C (и С++), чтобы утверждать, что правильность стиль. В самом деле, *
связывается с именем p
в грамматике.
"Типичный программист на С++" пишет int* p;
и объясняет, что "p
является указателем на тип подчеркивания int
". Действительно, тип p
равен int*
. Я явно предпочитаю этот акцент и считаю его важным для использования более продвинутых частей С++.
Ответ 2
Если бы я был опасен, я бы сказал, потому что люди С++ с большей вероятностью рассматривают информацию о типе как вещь сама по себе, потому что шаблоны позволяют манипулировать типами программно во время компиляции. Они также гораздо менее склонны объявлять несколько переменных в одной и той же декларации.
Стиль T*
фокусирует информацию о типе в одном месте и выделяет его, а путаница, которая будет введена с помощью такого синтаксиса с помощью T* foo, bar;
, не является проблемой, если вы никогда не объявляете две переменные в то же утверждение.
Лично я нахожу стиль T*
очень неприятным и очень не нравится. *
является частью информации о типе, это правда, но способ анализа его компилятором делает его фактически привязанным к имени, а не типу. Я думаю, что способ T*
скрывает что-то важное, что происходит.
В моих наблюдениях, похоже, я редкость в сообществе С++. Я заметил то же самое, что у вас есть о том, какой стиль является самым популярным.
Чтобы быть понятным, конечно, любой стиль работает на любом языке. Но я замечаю то же самое, что вы делаете, что один стиль имеет тенденцию быть немного более распространенным с C-кодом, а другой немного более распространенным с С++.
Ответ 3
Лично я бы не согласился с этим - я не думаю, что есть способ C или С++. Я никогда не видел никаких доказательств. Однако у меня есть гипотеза о том, почему синтаксис со звездочкой ближе к объявленному имени переменной в C.
В C (по крайней мере, на C89, подавляющем большинстве используемого C), вы должны объявить все свои переменные в верхней части блока. Это приводит к тому, что программисты делают
T a, b, c;
относительно часто, а на С++ это редко. (В С++ вы объявляете переменные, близкие к тому, где они используются, а переменные часто имеют параметры конструктора и т.д., Поэтому редко приходится объявлять несколько объектов в одной строке)
Это также единственный случай, когда синтаксис имеет значение, поскольку оператор
T* a, b, c;
объявляет один указатель, а не три, которые может ожидать программист.
Так как размещение более одного объявления в одной строке является более распространенным в C, а также является единственным случаем, когда положение звездочки имеет значение, более вероятно, что программист свяжет звездочку с переменной.
Тем не менее, я никогда не видел никаких доказательств этого - это просто догадка.
Ответ 4
Несколько человек упомянули очень хорошие моменты. Я просто хочу отметить, что, в то время как C сильно сохранил значение "декларация отражает использование", С++ этого не сделал. Несколько деклараторов на С++ не отражают использование в объявлениях;
int &ref; // but "&ref" has type "int*", not "int".
int &&ref; // but "&&ref" is not valid at all.
Я не думаю, что программисты на С++, пишущие его по-разному, действительно имеют это как свою причину, но это может быть что-то, что останавливает авторов книг на С++, чтобы они могли это упомянуть, что может повлиять на этих программистов на С++.
Ответ 5
Причина, по которой программисты C имеют тенденцию использовать один стиль, в то время как программисты на С++ используют другой стиль, очень просты: Керниган и Ричи использовали стиль "C" в их книга, в то время как Страуступ использовал "стиль C++" в свою книгу.
Ответ 6
В K & R они используют нотацию type *name
, поэтому может быть, что многие программисты C получили ее.
Ответ 7
Поскольку Бьярне имел преимущество задним числом: он понял, что синтаксис декларатора C был "экспериментом, который не удался" (читай: синтаксис C-декларатора замедлен). Остальное уже ответили другие.
Ответ 8
Я не думаю, что вы правы в своем различии,
Там С++ code в стиле T *
.
Там C code в стиле T*
.
Я думаю, это просто вопрос личного предпочтения участников проекта.
Ответ 9
Просто бросьте некоторые разногласия в этот вопрос:
- Пользователи С++ обычно заявляют, что одно объявление в строке делает все, чтобы поставить звездочку на тип (слева).
int* a; int* b;
- Оба C и С++ обрабатываются звездочкой, прикрепленной к имени (справа).
int *a;
- Препроцессоры С++ часто перемещают звездочку влево. Препроцессоры C перемещают его вправо.
- На любом языке, помещая его слева, будет выглядеть странно для объявления нескольких переменных одного и того же типа в одном и том же выражении.
int* a, * b, * c;
- Есть несколько синтаксических элементов, которые выглядят глупо с ним слева.
int* (* func)()
.
Существуют и другие элементы C, которые неправильно используются, например const
, который тоже принадлежит справа! int const a;
. Это обычно помещается слева от типа, несмотря на принадлежность к типу слева. Многие компиляторы должны быть модифицированы для обработки этого использования. В С++ вы можете заметить, что это соответствует постоянным методам, поскольку компилятор не может вывести для вас, если он поместил слева: int A::a() const
. Это также ломается при вложенном использовании const
, restricted
и друзей с такими объявлениями, как int const *
. Обычное использование const
предполагает, что это постоянный указатель на целое число, но на самом деле int *const
.
TL;DR
Вы все делали все неправильно, все делалось справа.
Ответ 10
Объявления C следуют тем же правилам (например, приоритет) в качестве выражений. На самом деле, совершенно правильно рассматривать декларацию типа
int *foo;
как объявление типа выражения *foo
(т.е. оператора косвенности, примененного к foo
) как int
вместо foo
как типа int*
.
Однако, как уже указывалось ранее, в С++ его общее представление о типах как отдельном, а также - из-за шаблонов - изменяемый объект, и поэтому имеет смысл использовать объявление типа
int* foo;