int * i; lub int * i; lub int * i; [Zamknięte]

30

Jaka jest twoja ulubiona metoda deklarowania wskaźnika?

int* i;

lub

int *i;

lub

int * i;

lub

int*i;

Proszę wyjaśnić dlaczego.

patrz także: http://www.stroustrup.com/bs_faq2.html#whitespace

lesmana
źródło
19
Wolałbym skupić się na pozostałych 3000 liniach ...
29
int*i;-
biała
To jest zasadniczo to samo pytanie; oto moja odpowiedź .
Keith Thompson

Odpowiedzi:

75

Jeśli napiszesz:

int* i, j, k;

mylnie sugerujesz, że wszystkie i, j i k są wskaźnikami do int.

Twierdzę więc, że lepiej jest dołączyć * do nazwy zmiennej.

Randall Schulz
źródło
35
I sugerowałbym, int * i;że nie konkuruje tylko dlatego, że na pierwszy rzut oka wygląda jak mnożenie.
John K,
1
+1, ponieważ wcześniej nie rozważałem tego scenariusza.
Wyskakuje
4
„sugerujesz, że wszystkie i, j i k są wskaźnikami do int.” Chyba że piszesz C #, gdzie int*jest postrzegane jako typ i int* i, jdeklaruje dwa wskaźniki. Pytanie można uznać za niekompletne - zależy to od używanego języka, które style są rozsądne. W CI wykonaj int *x, w C # robię inaczej.
Joren,
1
@Joren: Przepraszam, nie będąc programistą C #, po prostu założyłem, że patrząc na fragment kodu w pytaniu to C lub C ++.
Randall Schulz
Myślę, że całkowicie uzasadnione jest założenie, że jest to C lub C ++, chyba że C # jest wyraźnie wymienione. Wskaźniki w C # nie są często wyświetlane.
alternatywny
62

Wolę, int* iponieważ ima typ „wskaźnik do int” i czuję, że to czyni go jednolitym z systemem typów. Oczywiście pojawia się dobrze znane zachowanie podczas próby zdefiniowania wielu wskaźników w jednym wierszu (mianowicie gwiazdka musi być umieszczona przed każdą nazwą zmiennej, aby zadeklarować wskaźnik), ale po prostu nie deklaruję wskaźników w ten sposób. Ponadto uważam, że jest to poważna wada w językach w stylu C.

Tamás Szelei
źródło
8
Ja również przestrzegam tej konwencji. Z tego samego powodu.
gablin
5
Osobiście, jeśli deklaruję wiele wskaźników w moim kodzie, traktuję go jak zapach kodu. Nie powinienem potrzebować tylu wskaźników; i zwykle nie. Tak więc kwestia wielu deklaracji w jednym wierszu nigdy nie pojawia się w żadnym kodzie, który piszę: Jedna deklaracja na linię.
greyfade
5
Problem polega na tym, że typ nie jest „wskaźnikiem do int”. C (i C ++) nie ma typu wskaźnika. Jest to wskaźnik do bloku pamięci, którego typ to int.
Billy ONeal,
10
Twierdziłbym, że *ima pewien rodzaj int.
Tim Goodman,
5
@Billy: Jeśli tak, to nigdy nie widziałem tego zamieszania w ciągu 12 lat prób rozumienia, analizowania i wyjaśniania standardese. „Pointer to int” jest doskonale poprawnym typem w C i C ++.
23

W przypadku C, gdzie nie skupiamy się na typach, wolę:

int *i;

Ponieważ ma w sobie empirię int, a nie wskaźnik. Co to jest int? *ijest int.

alternatywny
źródło
2
Słuszna uwaga. Dzięki wskaźnikom możesz myśleć o początku jako o nazwie. Na przykład, jeśli masz int i = 5, aby uzyskać wartość i, użyj nazwy i. Podobnie, jeśli masz int *i; *i = 5, to aby uzyskać wartość, użyj *i.
mipadi
Czytam int * i jako: * i jest int. Dlatego i jest wskaźnikiem do int. Deklaracje zmiennych w wyrażeniach typu C, int i * są tylko operatorami. int * i analizuje jako int (* (i)) i jest interpretowane jako i ma typ wskaźnik do liczby całkowitej. char * p [] analizuje jako char (* ([] (p))) (ponieważ [] ma wyższy priorytet niż *) i oznacza: p ma typ tablica-typu wskaźnik-na char.
Giorgio
Z tego powodu myślę, że zdecydowali się napisać * obok zmiennej, ponieważ * jest operatorem zastosowanym do niej.
Giorgio
7

Wolę int* iod lat. Istnieje jednak mocny argument za tym, int *iże podczas korzystania z poprzedniego stylu nadal musisz pamiętać regułę wielokrotnej deklaracji:

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

Ponieważ musisz pamiętać tę zasadę, nie zyskujesz w prosty sposób - ale nie powiedziałbym, że jest bardziej złożona. Unikanie wielu deklaracji w jednym wierszu to kolejny sposób na powiedzenie, że pamiętasz tę regułę. Różnica między tymi dwoma stylami jest sporna.

Nawet gdy go używam, wydaje się to trochę głupie, aby udawać, że składnia deklaracji C działa inaczej niż ona, umieszczając gwiazdkę obok typu, a nie zmiennej, z którą jest on syntaktycznie związany.

Nie kupuję się, że jedna podkreśla typ wskaźnika (na i), podczas gdy drugi podkreśla typ int (za *i), ale może być tak, że po 15 latach C i C ++ użytku, to po prostu jest , gdy patrzę na nią, bez myśleć o tym… - coś, co większość początkujących, którzy zadają to pytanie, nie jest jeszcze w stanie tego zrobić.

Ponadto, nawet biorąc pod uwagę moje preferencje, nie jest mi trudno czytać / pisać kod w innym stylu. Spójność, bla bla bla.

Nie trzeba nawet wspominać int * i.


źródło
6

Wolę pierwszy. To naturalne, że wskaźnik jest częścią tego typu.

Gdy używam C #, obsługuje typy w bardziej intuicyjny sposób niż C, więc nie ma problemu z zadeklarowaniem kilku wskaźników w tej samej instrukcji:

int* a, b, c; // three pointers
Guffa
źródło
4

Jeśli chcesz zadeklarować wiele zmiennych, ale nie chcesz powtarzać gwiazdki:

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

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

(Jak widać w szablonie struktury, wolę int* istyl).

A oto bardziej ogólne rozwiązanie:

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

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

Ten działa z dowolnym „typem problematycznym”, na przykład tablicami i referencjami:

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

identity<int&>::type r1(*p1), r2(*p2), r3(*p3);
fredoverflow
źródło
omg, c ++ zawsze pokazuje mi coś nowego :). Dzięki!
Tamás Szelei
1
OMG, C ++ jest przerażający! typedef int* int_ptrzrobiłby lewę. Jasne, muszę zadeklarować nowy typedef dla różnych typów wskaźników, ale w praktyce ile to będzie? Osiem co najwyżej?
benzado
1
@benzado W praktyce nie potrzebujesz typedef ani żadnej z fantazyjnych sztuczek, które pokazałem, ponieważ żadna zdrowa osoba nie deklaruje wielu zmiennych w jednym wierszu. Wciąż jednak interesujące.
fredoverflow
2
Wiem, mówiłem więcej o tendencji programów C ++ do używania funkcji językowych tylko dlatego, że mogą.
benzado
@benzado: !!! Tak często to widziałem!
Giorgio
2

Wybrałbym, int* i;ponieważ pierwsza część oznacza typ zmiennej (wskaźnik do int), podczas gdy druga część oznacza name ( i). Nie ma dla mnie sensu, że ten typ inti nazwa to *i. Poza tym int * i;wygląda mi to na pomnożenie.

Allon Guralnek
źródło
Składnia deklaracji C nie jest spójna pod tym względem, ponieważ informacje o typie mogą łatwo znaleźć się po identyfikatorze: tablice są najczystszym przykładem.
@Roger: Wiem, ale to pytanie dotyczyło konkretnie jednej deklaracji zmiennej i nic więcej.
Allon Guralnek
Myślę, że to trochę w tym wpisuje. :) W moim rozumieniu pytanie dotyczy tego, którego stylu używasz wszędzie.
@Roger: Prawdopodobnie masz rację, ale moim celem było odpowiedzieć na pytanie OP: „Jaka jest twoja ulubiona metoda deklarowania wskaźnika?”. Oczywiście każdy może przyjrzeć się zagadnieniu przedstawionemu w pytaniu, a nawet tutaj jest zachęcany. Jako ktoś, kto nie rozwija się w C / C ++, czułem, że odejdzie zbyt daleko od mojej specjalizacji.
Allon Guralnek
2

W deklaracjach, których używam int * i;, czytasz to jako i is a pointer to an integer.

Wskaźnik przyczynia się zarówno do typu, jak i do zmiennej, więc powinien znajdować się na środku.

Dobrze jest unikać deklarowania wielu rzeczy w tym samym wierszu: int * i, j;

Tamara Wijsman
źródło
1

Właściwie korzystam ze wszystkich trzech konwencji w określonych okolicznościach. Na pierwszy rzut oka wydaje się niespójny, ale ...

  • int * gdy identyfikator nie jest obecny, aby wizualnie potwierdzić, że nazwa nie jest obecna.
  • int* intptrna typedefs i podobnych deklaracjach, aby wizualnie wzmocnić, że jest to część tego typu. Podobnie z deklaracjami wskaźnika funkcji:(int* (*foo)(int))
  • int *identifieroraz class &identifierparametry funkcji w celu wizualnego wzmocnienia, że ​​parametr jest potencjalnie tak zwanym parametrem „out”.
  • const int * const * constilekroć używam kwalifikatorów cv .
  • int * foo; w sprawie lokalnych deklaracji.

Chyba jestem trochę zorientowany wizualnie.

greyfade
źródło
1

W C nie ma typów wskaźników! Zatem „int *” nic nie znaczy. Gwiazdka jest zawsze powiązana z elementem zapisanym po prawej stronie, należy do elementu bezpośrednio do niej. „* i” to int. A ponieważ * i jest int, wynika z tego, że i jest wskaźnikiem int. Taka jest logika i dlatego „int * i” jest jedynym możliwym rozwiązaniem. Cała reszta to złudzenie (które w większości przypadków jest automatycznie korygowane przez kompilator). W C ++ i C # to coś innego. Ale dla C jest tylko jedna biblia: „Dennis M. Ritchie: Język programowania C”. Dennis (RIP!) Napisał: „int * i”. Nie ma potrzeby kwestionować tego.

Lexi Pim
źródło
6
„Nie ma typów wskaźników w C” - Skąd pomysł? int*jest typem wskaźnika.
Keith Thompson
-2

Używam, int *iponieważ łatwiej jest zauważyć, że jest wskaźnikiem, choć nie sądzę, żeby to naprawdę miało znaczenie.

tia
źródło