В C, каков правильный синтаксис для объявления указателей?

Я неопределенно вспоминаю наблюдение этого прежде в ответе на другой вопрос, но поиску не удалось привести к ответу.

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

Type* instance;

Или:

Type *instance;

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

17
задан Sinan Ünür 17 November 2011 в 03:05
поделиться

6 ответов

Это просто вопрос того, как вам нравится это читать.

Причина, по которой некоторые люди пишут так:

Type *instance;

заключается в том, что здесь говорится, что только экземпляр является указателем. Потому что если у вас есть список переменных:

int* a, b, c;

Только a является указателем, поэтому проще так:

int *a, b, c, *d;

Где и a и d являются указателями. На самом деле нет никакой разницы, это просто для удобства чтения.

Другим людям нравится, когда * находится рядом с типом, потому что (среди прочих причин) они считают его "указателем на целое число" и думают, что * относится к типу, а не к переменной.

Лично я всегда так делаю

Type *instance;

Но это действительно зависит от вас и от руководства по стилю кода вашей компании/школы.

24
ответ дан 30 November 2019 в 10:45
поделиться

Эти двое абсолютно одинаковы.

Однако для целей объявления нескольких переменных, как показано ниже:

int * p1, p2;

где p1 имеет тип указателя на int, а p2 имеет тип int. Если вы хотите объявить p2 как указатель на int, вы должны написать:

int *p1, *p2;
3
ответ дан 30 November 2019 в 10:45
поделиться

Любопытно, что это правило не применяется, если тип выводится в C ++ 0x.

int a;
decltype(&a) i, j;

И i, и j имеют тип int *.

1
ответ дан 30 November 2019 в 10:45
поделиться

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

int * pi, j;

объявляет указатель на int ( pi ) и int ( j ).

11
ответ дан 30 November 2019 в 10:45
поделиться

Я предпочитаю следующий стиль:

Type *pointer;

Почему? Потому что он соответствует образу мышления, который пытались установить создатели языка:

"Синтаксис объявления переменной имитирует синтаксис выражений, в которых эта переменная может появиться."

(The C Programming Language by Brian W. Kernighan & Dennis M. Ritchie, ansi c version, page 94)

Легко писать FORTRAN на любом языке, но вы всегда должны писать [язык программирования X] на [языке программирования X].

2
ответ дан 30 November 2019 в 10:45
поделиться

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

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 может укусить вас, если вы не будете осторожны.

7
ответ дан 30 November 2019 в 10:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: