В чем разница между float * varname и float * varname в классическом c - PullRequest
7 голосов
/ 25 января 2010

В чем разница между float * varname и float * varname в классическом C?

Ответы [ 6 ]

22 голосов
/ 25 января 2010

Форматирование. Вот и все. Они означают одно и то же.

То, куда вы помещаете пространство (или, если оно вообще есть), является вопросом предпочтения. Некоторые предпочитают * рядом с varname, чтобы вас не смущало что-то вроде:

float* a, b;

(здесь только a - указатель, b - нет)

Другие утверждают, что они никогда не объявляют несколько переменных одновременно, поэтому они предпочитают * рядом с плавающей точкой, поскольку это часть типа.

8 голосов
/ 25 января 2010

Разницы нет. Пробелы полностью игнорируются.

Однако учтите, что следующее может вводить в заблуждение:

float* var1, var2;

Случайное рассмотрение вышеизложенного привело бы вас к мысли, что и var1, и var2 являются указателями на float. Однако вы ошибаетесь, потому что это объявляет var1 как указатель на число с плавающей точкой, но var2 будет обычным числом с плавающей точкой.

4 голосов
/ 25 января 2010

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

float *foo, bar;

foo - указатель на число с плавающей запятой, но bar - просто число с плавающей запятой.

1 голос
/ 25 января 2010

В основном это вопрос стиля кодирования. Однако большинство программистов на Си предпочитают использовать второй вариант: float *var;, поскольку он ближе к тому, как синтаксис языка связывает звездочку *: * привязан к декларатору, а не к спецификатору типа.

Другими словами, программисты на С переводят float *var как *var типа float. но не var имеет тип float*.

Более подробное объяснение есть в статье Википедии Типы переменных C и объявления

Также вы можете найти вопрос Синтаксис указателя C: опрос стилей интересно.

0 голосов
/ 25 января 2010

Фактически нет никакой разницы; объявление анализируется , как если бы было написано float (*varname);.

В C и C ++ объявления сосредоточены вокруг выражений , а не объектов; в основном, форма объявления должна соответствовать форме выражения в исполняемом коде (IOW, объявление имитирует использование). Например, если у вас есть указатель на целое число с именем p и вы хотите получить доступ к этому целому числу значению , на которое указывает p, вы разыменовываете указатель следующим образом:

x = *p;

Тип выражения *p является целым; таким образом, объявление должно выглядеть как

int *p;

Аналогично, если у вас есть массив int с именем arr и вы хотите получить доступ к целочисленному значению в конкретном элементе i, вы должны написать

x = a[i];

Тип выражения a[i] является целым; таким образом, объявление должно выглядеть как

int a[N];

В приведенных выше примерах *p и a[N] называются деклараторами ; объявители вводят имя объявляемого объекта вместе с дополнительной информацией о типе, не предоставленной в спецификаторе типа . Целочисленность p и a обеспечивается спецификатором типа int, но указатель p и массив a обеспечиваются их соответствующими деклараторами .

Это важный момент, который нужно подчеркнуть; * как int *p;, так и int* p; привязаны к декларатору , а не к спецификатору типа, независимо от пробелов. Тот факт, что вы можете написать это в любом случае, является случайностью синтаксиса C (и C ++), и в результате есть школа мысли, что переменные-указатели должны быть объявлены как T* p;, а не T *p;, так как type из p - это «указатель на T». Моя проблема в том, что рассуждения only работают для простых типов указателей; мы не можем обращаться с массивами или типами функций одинаково. Например, мы не можем записать int[N] arr;, даже если тип из arr равен «N-элементному массиву int». Это действительно падает, когда мы начинаем объявлять указатели на массивы, или указатели на функции, или их комбинации. Например:

int *(*(*(*farr)())[N])();

Тип из farr - это «указатель на функцию, возвращающую указатель на N-элементный массив указателей на функции, возвращающие указатели на int». Все, кроме «int», является частью объявления; писать int* (*(*(*farr)())[N])(); или даже int*(*(*(* farr)())[N])(); было бы просто ... глупо.

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

Поскольку я являюсь частью большой команды, пишущей код на C ++, я следую согласованным рекомендациям по кодированию, которые включают объявление указателя и ссылок как T* p; и T& r;, но это заставляет меня скрипеть зубами каждый раз, когда у меня есть сделать это.

0 голосов
/ 25 января 2010

Как говорили другие, это не имеет значения - вопрос стиля. Обратите внимание, что в C ++ принято писать:

type* var;

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...