Deklaracje C opierają się na typach wyrażeń , a nie obiektach.
Jeśli masz wskaźnik do int
nazwie pi
i chcesz uzyskać dostęp wartość całkowitą, która wskazuje na to, masz do nieprawidłowego wskaźnika, na przykład:
x = *pi;
printf("%d", *pi);
*pi = 1 + 2;
etc.Rodzaj ekspresji*pi
jest int
: zatem deklaracja powinna odczytywać jako
int *pi;
Teraz załóżmy miał tablicę wskaźników do char
; aby dostać się do dowolnego znaku, należy do pierwszego indeksu do tablicy, a następnie nieprawidłowego wyniku:
c = *pc[i];
if (*pc[j] == 'a') {...}
itd. Ponownie, rodzaj ekspresji*pc[i]
jest char
na , więc deklaracja brzmi
char *pc[N];
Zarówno *pi
i *pc[N]
są znane jako declarators i określ dodatkowe informacje o typie nie podane przez specyfikatora typu. IOW, array-ness i wskaźnik pc
są określone jako część deklaratora, natomiast char
-ness jest określony przez specyfikator typu.
Co do kwestii, które jest styl jest właściwa ...
Ani jeden jest „prawo”, ale ja (i wielu innych programistów C) wolą pisać T *p
w przeciwieństwie do T* p
, ponieważ ściślej odzwierciedla gramatykę języka (*
jest częścią deklaratora) i pomaga uniknąć nieporozumień podczas deklarowania wielu elementów. Widziałem daleko zbyt wiele przykładów osób piszących T* a, b;
i oczekujących, że b
będzie wskaźnikiem.
Zwykłą reakcją na tę krytykę jest "nie zadeklaruj więcej niż jednego produktu w wierszu". Moja odpowiedź na tę odpowiedź brzmi: "napisz poprawnie swoich deklaratorów i nie będziesz miał żadnych problemów".
Jest inna szkoła myślenia wśród wielu programistów C++, którzy preferują styl T* p
, i muszę powiedzieć, że istnieje kilka przypadków (ograniczone do C++), gdzie może uczynić kod bardziej czytelnym.
Jednak działa to tylko w przypadku prostych wskaźników do T
: paradygmat ulega szybkiemu zerwaniu, gdy zaczynasz radzić sobie z tablicami wskaźników lub wskaźników do tablic lub wskaźników do funkcji, lub wskaźników do tablic wskaźników do funkcji itp. Chodzi o to, że napisanie czegoś takiego, jak
T* (*(*p)[N])(); // p is a pointer to an array of pointers to functions
// returning pointers to T.
tylko wskazuje mylić myśli. Chociaż, jeśli naprawdę naprawdę naprawdę czujesz, że musi śledzić T* p
paradygmatu, zawsze można stworzyć serię typedefs:
EDIT
spróbujmy jeszcze raz:
typedef T* TPtr; // pointer to T
typedef TPtr TPtrFunc(); // function returning pointer to T
typedef TPtrFunc* TPtrFuncPtr; // pointer to function returning
// pointer to T
typedef TPtrFuncPtr TPtrFuncPtrArray[N]; // N-element array of pointer to function
// returning pointer to T
TPtrFuncPtrArray* p;
Z miłości do Boga, nie rób tego.
Nie wiem, dlaczego ludzie głosują, aby to zamknąć.To brzmi jak uzasadnione pytanie do mnie, ale potem hackowałem C tylko od 1980 roku. –
@PeterRowell: jedynym problemem z tego rodzaju banalnym pytaniem jest to, że można znaleźć odpowiedź na to w Internecie przez Google lub dowolne inne wyszukiwanie silnik w ciągu kilku sekund. I każda przyzwoita książka na C też musi to wyjaśnić. Dlaczego ich nie używać? Nie głosowałem, żeby to zamknąć. –
możliwy duplikat [Czy to ważne, gdzie umieszczam gwiazdkę podczas deklarowania wskaźników w C++?] (Http://stackoverflow.com/questions/5449908/does-it-matter-where-i-place-the-asterisk-when -deklaring-pointers-in-c) –