int * i; або int * i; або int * i; [зачинено]


30

Який ваш улюблений метод оголошення вказівника?

int* i;

або

int *i;

або

int * i;

або

int*i;

Поясніть, будь ласка, чому.

див. також: http://www.stroustrup.com/bs_faq2.html#whitespace


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", і я вважаю, що це робить його рівномірним із системою типів. Звичайно, відома поведінка виникає, коли намагаються визначити кілька покажчиків на одному рядку (а саме зірочку потрібно ставити перед кожним іменем змінної, щоб оголосити вказівник), але я просто не оголошую вказівники таким чином. Крім того, я думаю, що це серйозний дефект у мовах стилю С.


8
Я теж дотримуюся цієї конвенції. З тієї ж причини.
габлін

5
Особисто, якщо я оголошую кілька вказівників у своєму коді, я сприймаю це як запах коду. Мені не потрібно багато покажчиків; і зазвичай я цього не роблю. Тож випуск декількох декларацій в одному рядку ніколи не виникає в жодному коді, який я пишу: Одне оголошення на рядок.
greyfade

5
Проблема в цьому полягає в тому, що тип не є "покажчиком на int". C (і C ++) не мають типу вказівника. Це вказівник на блок пам’яті, до якого вводиться тип int.
Біллі ONeal

10
Я б заперечив, що *iмає тип int.
Тім Гудман

5
@Billy: Якщо так, я ніколи не бачив цієї плутанини за 12 років, намагаючись зрозуміти, проаналізувати та пояснити стандарти. "Вказівник на інт" - цілком коректний тип C і C ++.

23

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

int *i;

Тому що він має імпресію на int, а не на вказівник. Що таке int? *iє int.


2
Влучне зауваження. За допомогою покажчиків ви можете вважати початок частиною назви. Наприклад, якщо у вас є int i = 5, щоб отримати значення i, ви використовуєте ім'я i. Так само, якщо у вас є int *i; *i = 5, то для отримання значення ви використовуєте *i.
mipadi

Я читаю int * i як: * i є int. Тому я - покажчик на Int. Змінні декларації в виразах типу C, int та * - це лише оператори. int * i аналізує як int (* (i)) і інтерпретується так, як я має тип покажчика на ціле число. char * p [] розбирає як char (* ([] (p))) (тому що [] має більший пріоритет, ніж *) і означає: p має тип масиву-покажчика до 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


4

Якщо ви хочете оголосити кілька змінних, але не хочете повторити зірочку:

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

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

(Як ви бачите всередині шаблону struct, я віддаю перевагу 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);

omg, c ++ завжди показує щось нове для мене :). Спасибі!
Tamás Szelei

1
OMG, C ++ жахливо! typedef int* int_ptrзробив би трюк. Звичайно, я повинен оголосити новий typedef для різних типів вказівника, але на практиці скільки це буде? Найбільше вісім?
бензадо

1
@benzado На практиці вам не потрібен typedef або будь-який із химерних хитрощів, які я продемонстрував, тому що жодна розумна людина не оголошує декілька змінних в одному рядку. Ще цікаво, хоча.
fredoverflow

2
Я знаю, я говорив більше про тенденцію програм C ++ використовувати мовні функції лише тому, що вони можуть.
бензадо

@benzado: !!! Я бачив це так часто!
Джорджіо

2

Я б продовжував, int* i;оскільки перша частина позначає тип змінної (вказівник на int), а друга частина позначає ім'я ( i). Мені не було б сенсу, що тип є intі ім'я *i. Крім того, int * i;трохи схоже на множення.


Синтаксис декларації C не є послідовним у цьому плані, оскільки інформація про тип може легко прийти після ідентифікатора: найяскравіший приклад - масиви.

@Roger: Я знаю, але це питання стосувалося конкретно однієї змінної декларації, і нічого іншого.
Аллон Гуралнек

Я думаю, що це читає трохи в цьому. :) Наскільки я розумію питання, це запитання про те, який стиль ви використовуєте всюди.

@Roger: Ви, мабуть, маєте рацію, але моя мета полягала в тому, щоб відповісти на питання ОП: "Який ваш улюблений метод оголошення вказівника?". Очевидно, що кожен може вільно поглянути на питання, викладене в питанні, і це навіть заохочується. Як хтось, хто не розвивається в 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на функціональних параметрах візуально підсилити, що параметр потенційно є так званим параметром «поза».
  • const int * const * constвсякий раз , коли я використовую резюме класифікаторів.
  • int * foo; про місцеві декларації.

Я думаю, я дещо зорієнтований візуально.


1

У C немає типів вказівників! Отже, "int *" нічого не означає. Зірочка завжди пов'язана з елементом, написаним правом на неї, вона належить до правого елемента. "* i" - це int. А оскільки * i - це int, то випливає, що i - вказівник на int. У цьому полягає логіка, і саме тому "int * i" є єдиним можливим рішенням. Все інше - це ілюзія (яка у більшості випадків автоматично виправляється компілятором). У C ++ і C # це щось інше. Але для C існує лише одна біблія: "Денніс М. Річі: Мова програмування на С". Денніс (RIP!) Написав це: "int * i". Не потрібно в цьому сумніватися.


6
"У C немає типів вказівників" - Де ви взяли цю думку? int*- тип вказівника.
Кіт Томпсон

-2

Я використовую, int *iтому що легше бачити, що це вказівник, хоча я не думаю, що це насправді має значення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.