Почему считается, что 'T *name' - это путь C, а 'T *name' - как путь C++?

Примечание: этот вопрос о позиции звездочки (*).

В большинстве кода C, который я вижу (например, в руководстве по сетевому программированию Beej), все объявления / определения переменных используют T *name формат, то есть, связать * к имени переменной. Указатель считается принадлежащим переменной, а не типу.

В большинстве кода C++, который я вижу, формат T* nameто есть связывает * к типу переменной. Указатель считается принадлежащим типу, а не переменной. Я сам, как чистый C++ кодер, также использую этот формат, так как указатель на тип явно (для меня) относится к типу, а не к переменной. (Кстати, даже стандарт C++ использует этот формат в примерах.:))

Есть ли (историческая) причина для этого? Изменился ли образ мышления, когда программисты начали заниматься C++?

Было бы также хорошо, если бы C-кодер (который использует первый формат) мог объяснить, почему он / она использует его, а не последний.

10 ответов

Решение

Из часто задаваемых вопросов о стиле и методике Страуструпа.

"Типичный программист C" пишет int *p; и объясняет это*p это то, что int"подчеркивая синтаксис, и может указывать на грамматику объявления C (и C++), чтобы аргументировать правильность стиля. Действительно, * привязывается к имени p в грамматике.

"Типичный программист C++" пишет int* p; и объясняет этоp это указатель на int"подчеркивающий тип. Действительно тип p является int*, Я явно предпочитаю этот акцент и считаю его важным для хорошего использования более продвинутых частей C++.

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

T* Стиль сосредотачивает информацию о типе в одном месте и выделяет ее, а также путаницу, которая может возникнуть из-за чего-то вроде T* foo, bar; с этим синтаксисом не проблема, если вы никогда не объявляете две переменные в одном выражении.

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

В моих наблюдениях кажется, что я редкость в сообществе C++. Я заметил то же самое, что и у вас, о том, какой стиль наиболее популярен.

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

Лично я не согласился бы с этим - я не думаю, что есть способ C или C++ сделать это. Я никогда не видел никаких доказательств, чтобы это предположить. Тем не менее, у меня есть гипотеза о том, почему синтаксис со звездочкой ближе к объявленному имени переменной в C.

В C (по крайней мере, в C89, подавляющем большинстве C), вы должны объявить все свои переменные в верхней части блока. Это приводит к тому, что программисты делают

T a, b, c;

относительно часто, в то время как в C++ это редко. (В C++ вы объявляете переменные рядом с тем местом, где они используются, а переменные часто имеют параметры конструктора и т. Д.; поэтому редко объявлять несколько объектов в одной строке)

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

T* a, b, c;

объявляет один указатель, а не три, которые может ожидать программист.

Поскольку размещение более чем одной декларации в одной строке более распространено в C, а также является единственным случаем, когда положение звездочки имеет значение, программист с большей вероятностью связывает звездочку с переменной.

Тем не менее, я никогда не видел никаких доказательств этого - это всего лишь догадка.

Несколько человек упомянули очень хорошие моменты. Я просто хочу отметить, что, хотя C очень сильно сохранил значение "объявление отражает использование", C++ этого не сделал. Несколько объявлений в C++ не отражают использование в объявлениях;

int &ref; // but "&ref" has type "int*", not "int".
int &&ref; // but "&&ref" is not valid at all.

Я не думаю, что программисты на C++, пишущие по-другому, на самом деле имеют такую ​​причину, но это может быть чем-то, что мешает авторам книг C++ упомянуть об этом, что может повлиять на программистов на C++.

Причина, по которой программисты на C склонны использовать один стиль, в то время как программисты на C++ используют другой стиль, довольно проста: Kernighan & Ritchie использовали "стиль C" в своей книге, в то время как Страуструп использовал "стиль C++" в своей книге.

В K&R они используют type *name нотация, так что, может быть, это то, где многие программисты C получили это.

Потому что Бьярне имел преимущество в ретроспективе: он понял, что синтаксис объявления C был "экспериментом, который не удался" (читай: синтаксис объявления C запаздывает). На остальные уже ответили другие.

Просто, чтобы бросить спор в этот вопрос:

  • Пользователи C++ обычно заявляют, что одно объявление на строку позволяет поставить звездочку на тип (слева). int* a; int* b;
  • И C, и C++ анализируются со звездочкой, прикрепленной к имени (справа). int *a;
  • Препроцессоры C++ часто перемещают звездочку влево. С препроцессорами передвиньте его вправо.
  • В любом языке, размещение его слева будет выглядеть странно для объявления нескольких переменных одного типа в одном выражении. int* a, * b, * c;
  • Есть некоторые синтаксические элементы, которые выглядят глупо с левой стороны. int* (* func)(),

Есть другие элементы C, которые используются неправильно, такие как const, который принадлежит справа тоже! int const a;, Обычно это ставится слева от типа, несмотря на принадлежность к типу слева от него. Многие компиляторы должны быть изменены для обработки этого использования. В C++ вы можете наблюдать, что это согласуется с константными методами, так как компилятор не может вывести вас, если он помещен слева: int A::a() const, Это также ломает с вложенным использованием const, restricted и дружит с такими декларациями как int const *, Обычное использование const предположил бы, что это постоянный указатель на целое число, но это на самом деле int *const,

ТЛ; др

Вы все делали все это неправильно, все расставляли правильно.

Я не думаю, что ты прав насчет своего различия,

Там есть код C++ в T * стиль.

Там есть код C в T* стиль.

Я думаю, что это просто вопрос личных предпочтений участников проекта.

Объявления C следуют тем же правилам (например, приоритет), что и выражения. На самом деле, совершенно правильно рассматривать декларацию как

int *foo;

как объявление типа выражения *foo (т.е. оператор косвенности применяется к foo) как int вместо foo как тип int*,

Однако, как уже указывалось ранее, в C++ принято думать о типах как об отдельном и - из-за шаблонов - изменяемой сущности, и поэтому имеет смысл использовать объявление вроде

int* foo;
Другие вопросы по тегам