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
int*i;
-
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
int*i;
-
Odpowiedzi:
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.
int * i;
że nie konkuruje tylko dlatego, że na pierwszy rzut oka wygląda jak mnożenie.
int*
jest postrzegane jako typ i int* i, j
deklaruje 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.
Wolę, int* i
ponieważ i
ma 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.
*i
ma pewien rodzaj int
.
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
? *i
jest int.
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
.
Wolę int* i
od 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
.
Wolę int* i
(styl C ++).
Unikam deklarowania wielu zmiennych w jednej instrukcji ze względu na wynikową niejednoznaczność wizualną ( int* i, j
).
Zobacz także często zadawane pytania dotyczące stylu i techniki Cj Bjarne Stroustrup w C ++ .
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* i
styl).
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);
typedef int* int_ptr
zrobił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?
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 int
i nazwa to *i
. Poza tym int * i;
wygląda mi to na pomnożenie.
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;
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* intptr
na typedef
s i podobnych deklaracjach, aby wizualnie wzmocnić, że jest to część tego typu. Podobnie z deklaracjami wskaźnika funkcji:(int* (*foo)(int))
int *identifier
oraz class &identifier
parametry funkcji w celu wizualnego wzmocnienia, że parametr jest potencjalnie tak zwanym parametrem „out”.const int * const * const
ilekroć używam kwalifikatorów cv .int * foo;
w sprawie lokalnych deklaracji.Chyba jestem trochę zorientowany wizualnie.
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.
int*
jest typem wskaźnika.