int * i; или int * i; или int * i; [закрыто]

30

Какой ваш любимый способ объявить указатель?

int* i;

или

int *i;

или

int * i;

или

int*i;

Пожалуйста, объясните почему.

см. также: http://www.stroustrup.com/bs_faq2.html#whitespace

lesmana
источник
19
Я бы предпочел сосредоточиться на других 3000 строк ...
29
int*i;- Пробелы не растут на деревьях, вы знаете ...
Shog9
Это по сути тот же вопрос; вот мой ответ .
Кит Томпсон

Ответы:

75

Если вы напишите:

int* i, j, k;

Вы вводите в заблуждение, что все i, j и k являются указателями на int.

Поэтому я утверждаю, что лучше приложить * к имени переменной.

Рэндалл Шульц
источник
35
И я бы посоветовал int * i;не претендовать только потому, что на первый взгляд это выглядит как умножение.
Джон К
1
+1, потому что я не рассматривал этот сценарий раньше.
появляется
4
«Вы вводите в заблуждение, что все i, j и k являются указателями на int». Если вы не пишете на C #, где int*рассматривается как тип и int* i, jобъявляет два указателя. Вопрос может считаться неполным - это зависит от языка, который вы используете, какие стили являются разумными. В CI следуйте int *x, в C # я делаю иначе.
Джорен
1
@Joren: Извините, я не программист на C #, просто предположил, что фрагмент кода в вопросе был C или C ++.
Рэндалл Шульц
Я думаю, что вполне разумно предположить, что это C или C ++, если только C # не упоминается особо. Никто не видит указатели в C # очень часто.
альтернатива
62

Я предпочитаю, int* iпотому что iимеет тип «указатель на int», и я чувствую, что это делает его единым с системой типов. Конечно, хорошо известное поведение проявляется при попытке определить несколько указателей в одной строке (а именно, звездочку нужно ставить перед каждым именем переменной для объявления указателя), но я просто не объявляю указатели таким образом. Кроме того, я думаю, что это серьезный дефект в языках C-стиля.

Тамас Селеи
источник
8
Я тоже следую этому соглашению. По той же причине.
Габлин
5
Лично, если я объявляю несколько указателей в своем коде, я воспринимаю это как запах кода. Мне не нужно столько указателей; и обычно нет. Таким образом, проблема нескольких объявлений в одной строке никогда не возникает в любом написанном мною коде: одно объявление в строке.
Greyfade
5
Проблема в том, что тип не является «указателем на int». C (и C ++) не имеет указатель типа. Это указатель на блок памяти, тип которого int.
Билли ONEAL
10
Я бы сказал, что *iимеет тип int.
Тим Гудман
5
@ Билли: Если так, то я никогда не видел такой путаницы за 12 лет попыток понять, проанализировать и объяснить стандарт. «Указатель на int» является совершенно допустимым типом в C и C ++.
23

Для C, где у нас нет сильного внимания к типам, я предпочитаю:

int *i;

Потому что он имеет упор на int, а не указатель. Что это int? *iэто инт.

альтернатива
источник
2
Хорошая точка зрения. С помощью указателей вы можете думать о начале как о части имени. Например, если у вас есть int i = 5, чтобы получить значение i, вы используете имя i. Точно так же, если у вас есть int *i; *i = 5, то чтобы получить значение, вы используете *i.
Мипади
Я читаю int * i как: * я - int. Поэтому я указатель на int. Объявления переменных в C используют выражения типов, int и * являются просто операторами. int * i анализируется как int (* (i)) и интерпретируется как целое число указателя типа. char * p [] анализируется как char (* ([] (p))) (потому что [] имеет более высокий приоритет, чем *) и означает: p имеет тип array-of-pointer-to char.
Джорджио
По этой причине я думаю, что они решили написать * рядом с переменной, потому что * это оператор, применяемый к ней.
Джорджио
7

Я предпочел в int* iтечение многих лет. Однако есть веский аргумент, int *iпотому что при использовании предыдущего стиля вы все равно должны помнить правило множественного объявления:

int* a, *b; // not int* a, b;

Поскольку вы должны помнить это правило, вы не получите ничего в явном виде, но я бы не сказал, что оно более сложное. Избегание нескольких объявлений в одной строке - это просто еще один способ сказать, что вы помните это правило. Разница между этими двумя стилями спорна.

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

Я не покупаю в том , что один подчеркивает тип указателя (для i) , а другой подчеркивает тип INT (для *i), но это может быть , что после 15 лет использования С и С ++, это просто есть , когда я смотрю на него, без необходимость думать об этом »-« что-то, что большинство новичков, которые задают этот вопрос, еще не могут сделать.

Кроме того, даже учитывая мои предпочтения, я не считаю неловким чтение / запись кода в другом стиле. Последовательность, бла-бла-бла.

Не нужно даже упоминать int * i.


источник
6

Я предпочитаю первый. Это естественно, так как указатель является частью типа.

Поскольку я использую C #, он обрабатывает типы более интуитивно понятным способом, чем C, поэтому нет проблем с объявлением нескольких указателей в одном выражении:

int* a, b, c; // three pointers
Guffa
источник
5

Я предпочитаю int* i(стиль C ++).
Я избегаю объявлять несколько переменных в одном выражении из-за возникающей визуальной неоднозначности ( int* i, j).

См. Также Bjarne Stroustrup's C ++ Style and Technique FAQ для обоснования.

Archimedix
источник
4

Если вы хотите объявить несколько переменных, но не хотите повторять звездочку:

template <typename T>
struct pointer_to
{
    typedef T* type;
};

pointer_to<int>::type p1, p2, p3;

(Как вы можете видеть внутри шаблона структуры, я предпочитаю int* iстиль.)

А вот более общее решение:

template <typename T>
struct identity
{
    typedef T type;
};

identity<int*>::type p1, p2, p3;

Этот работает с любым «проблемным типом», например, массивами и ссылками:

identity<int[10]>::type a1, a2, a3;

identity<int&>::type r1(*p1), r2(*p2), r3(*p3);
fredoverflow
источник
о боже мой, с ++ всегда показывает что-то новое для меня :). Благодарность!
Тамас Селеи
1
OMG, C ++ ужасает! typedef int* int_ptrсделал бы свое дело. Конечно, я должен объявить новый typedef для разных типов указателей, но на практике, сколько это будет? Восемь максимум?
Бензадо
1
@benzado На практике вам не нужны typedef или какие-либо изощренные трюки, которые я продемонстрировал, потому что ни один здравомыслящий человек не объявляет несколько переменных в одной строке. Тем не менее, интересно.
fredoverflow
2
Я знаю, я больше говорил о склонности программ на С ++ использовать языковые функции только потому, что они могут.
Бензадо
@benzado: !!! Я видел это так часто!
Джорджио
2

Я бы пошел, int* i;так как первая часть обозначает тип переменной (указатель на int), а вторая часть обозначает имя ( i). Для меня не имеет смысла, что тип intи имя *i. Кроме того, int * i;для меня это выглядит как умножение.

Аллон Гуралнек
источник
Синтаксис объявления C в этом отношении непоследователен, так как информация о типе может легко появиться после идентификатора: наиболее ярким примером являются массивы.
@ Роджер: Я знаю, но этот вопрос был конкретно о единственном объявлении переменной, и ничего больше.
Аллон Гуралнек
Я думаю, что это очень много читает. :) То, как я понимаю вопрос, это вопрос о том, какой стиль вы используете везде.
@ Роджер: Вы, вероятно, правы, но моя цель состояла в том, чтобы ответить на вопрос ОП: «Какой ваш любимый способ объявления указателя?». Очевидно, что каждый может свободно взглянуть на проблему, представленную в вопросе, и здесь это даже поощряется. Как человек, который не разрабатывает на C / C ++, я чувствовал, что это слишком далеко от моей области знаний.
Аллон Гуралнек
2

В декларациях, которые я использую int * i;, вы читаете это как i is a pointer to an integer.

Указатель вносит вклад как в тип, так и в переменную, поэтому он должен быть посередине.

Это хорошая вещь, чтобы избежать объявления нескольких вещей в одной строке: int * i, j;

Тамара Вийсман
источник
1

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

  • int * когда идентификатор отсутствует, визуально подтвердить, что имя отсутствует.
  • int* intptrна typedefs и подобные объявления, чтобы визуально подтвердить, что это часть типа. Аналогично с объявлениями указателей на функции:(int* (*foo)(int))
  • int *identifierи class &identifierна параметры функции для визуального подтверждения того, что параметр потенциально является так называемым параметром «out».
  • const int * const * constвсякий раз, когда я использую квалификаторы cv .
  • int * foo; на местных декларациях.

Я думаю, что я немного визуально ориентирован.

greyfade
источник
1

В C нет типов указателей! Итак, «int *» ничего не значит. Звездочка всегда связана с элементом, написанным справа от него, она относится к элементу права на него. "* я" является int. И поскольку * i является int, из этого следует, что i является указателем на int. Это логика, и именно поэтому «int * i» является единственно возможным решением. Все остальное - иллюзия (которая в большинстве случаев автоматически исправляется компилятором). В C ++ и C # это что-то другое. Но для Си есть только одна библия: «Деннис М. Ричи: Язык программирования Си». Деннис (RIP!) Написал это: "int * i". Нет необходимости подвергать сомнению это.

Лекси Пим
источник
6
«В С нет типов указателей» - Откуда вы взяли эту идею? int*тип указателя
Кит Томпсон
-2

Я использую, int *iпотому что легче понять, что это указатель, хотя я не думаю, что это действительно важно.

ТИА
источник