Я неопределенно вспоминаю наблюдение этого прежде в ответе на другой вопрос, но поиску не удалось привести к ответу.
Я не могу вспомнить то, что является надлежащим способом объявить переменные, которые являются указателями. Это:
Type* instance;
Или:
Type *instance;
Хотя я знаю, что оба скомпилируют в большинстве случаев, я полагаю, что существуют некоторые примеры, где это значительно, возможно связанное с объявлением нескольких переменных того же типа на той же строке, и таким образом, каждый имеет больше смысла, чем другой.
Это просто вопрос того, как вам нравится это читать.
Причина, по которой некоторые люди пишут так:
Type *instance;
заключается в том, что здесь говорится, что только экземпляр является указателем. Потому что если у вас есть список переменных:
int* a, b, c;
Только a является указателем, поэтому проще так:
int *a, b, c, *d;
Где и a и d являются указателями. На самом деле нет никакой разницы, это просто для удобства чтения.
Другим людям нравится, когда * находится рядом с типом, потому что (среди прочих причин) они считают его "указателем на целое число" и думают, что * относится к типу, а не к переменной.
Лично я всегда так делаю
Type *instance;
Но это действительно зависит от вас и от руководства по стилю кода вашей компании/школы.
Эти двое абсолютно одинаковы.
Однако для целей объявления нескольких переменных, как показано ниже:
int * p1, p2;
где p1 имеет тип указателя на int, а p2 имеет тип int. Если вы хотите объявить p2 как указатель на int, вы должны написать:
int *p1, *p2;
Любопытно, что это правило не применяется, если тип выводится в C ++ 0x.
int a;
decltype(&a) i, j;
И i, и j имеют тип int *.
Эти двое одинаковы. Однако, если вы делаете несколько объявлений, первое может заманить вас в ловушку.
int * pi, j;
объявляет указатель на int ( pi
) и int ( j
).
Я предпочитаю следующий стиль:
Type *pointer;
Почему? Потому что он соответствует образу мышления, который пытались установить создатели языка:
"Синтаксис объявления переменной имитирует синтаксис выражений, в которых эта переменная может появиться."
(The C Programming Language by Brian W. Kernighan & Dennis M. Ritchie, ansi c version, page 94)
Легко писать FORTRAN на любом языке, но вы всегда должны писать [язык программирования X] на [языке программирования X].
Это случайность синтаксиса языка Си, что вы можете написать это так или иначе; однако, это всегда разбирается как
Type (*pointer);
то есть, *
всегда привязывается к декларатору, а не к спецификатору типа. Если бы вы написали
Type* pointer1, pointer2;
то это было бы разобрано как
Type (*pointer1), pointer2;
поэтому только pointer1 был бы объявлен как тип pointer.
В языке C используется парадигма "объявление имитирует использование"; структура объявления должна максимально имитировать эквивалентное выражение, используемое в коде. Например, если у вас есть массив указателей на int с именем arr
, и вы хотите получить целочисленное значение, на которое указывает i-й элемент в массиве, вы подрисуете массив и разыменуете результат, который записывается как *arr[i]
(разбирается как *(arr[i])
). Типом выражения *arr[i]
является int
, поэтому объявление для arr
записывается как
int *arr[N];
Какой способ правильный? Зависит от того, кого вы спросите. Старые пердуны на Си, вроде меня, предпочитают T *p
, потому что он отражает то, что на самом деле происходит в грамматике. Многие программисты C++ предпочитают T* p
, потому что он подчеркивает тип p
, который кажется более естественным во многих обстоятельствах (написав свои собственные контейнерные типы, я могу понять суть, хотя мне это все еще кажется неправильным).
Если вы хотите объявить несколько указателей, вы можете либо объявить их все явно, например:
T *p1, *p2, *p3;
либо создать typedef:
typedef T *tptr;
tptr p1, p2, p3;
хотя я лично не рекомендую этого делать; скрытие указательности чего-либо за typedef может укусить вас, если вы не будете осторожны.