2010-09-21 10 views
6

Mam pytanie, które jest w pewien sposób, jak sądzę, całkowicie banalne: co to jest (i dlaczego)?Niejasna deklaracja wskaźnika

const float *(*const*)(int) 

moim rozumieniu jest to, że jest „wskaźnik do stałego wskaźnika do funkcji biorąc int jako argument i powrocie wskaźnik do stałej pływaka”.

Czy to prawda?

Jak "zanalizować mentalnie" (*const*)? Zwłaszcza, że ​​nie ma imienia, na początku nie wiedziałem, od czego zacząć. Myślę, że jedyną możliwością dla "nazwy" byłoby umieszczenie tego w ten sposób: *const *name, ponieważ inna kombinacja jest nieważna (jeśli mam rację), więc "nazwa to wskaźnik do wskaźnika stałego ...".

Czy to uzasadnienie jest ważne?

Dzięki!

+4

Staram się unikać takich głupich definicji, dzieląc je na komponenty za pomocą typedef. –

+1

c giggerish do EN: "http://cdecl.ridiculousfish.com/?q=const+float+*%28*const*+foo%29%28int%29" – Anycorn

+0

Dla każdego, kto ma problemy z podłączeniem powyższego kodu do kompilatora spróbuj umieścić go jako parametr w prototypie funkcji 'int foo (const float * (* const *) (int));' który jest taki sam jak 'int foo (const float * (* const * nazwa_zmienki) (int)) ; ' – nategoose

Odpowiedz

6

Tak, to uzasadnienie jest ważne. Umieść go po prawej stronie wszystkich "*", które nie znajdują się na listach parametrów funkcji i po lewej stronie wszystkich [], które nie znajdują się na listach parametrów funkcji. Następnie masz

const float *(*const* name)(int) 

Następnie przeczytaj to jak zwykle. Od tego miejsca, a nawet jak znaleźć właściwe miejsce na nazwę, wiele tutoriali, jak parsować to w Internecie.

Dla C++ możesz zajrzeć do geordi.

< litb> geordi: -c int name; 
< geordi> Success 
< litb> geordi: make name a const float *(*const*)(int) and show 
< geordi> -c float const *(*const* name)(int) ; 
< litb> geordi: << TYPE_DESC(const float *(*const*)(int)) 
< geordi> pointer to a constant pointer to a function taking an integer 
      and returning a pointer to a constant float 

Następnie można zrobić analizę składni nim

< litb> geordi: show parameter-declaration and first decl-specifier-seq 
< geordi> `int` and `float const`. 
< litb> geordi: make name an array of 2 pointer to function taking int and 
     returning pointer to float and show 
< geordi> -c float const *(* name[2])(int); 

To pozwala mieszać C z angielskiego

< litb> geordi: make name an array of 2 pointer to (float const*(int)) and show 
< geordi> -c const float *(* name[2])(int); 

Jak widać, jest to dość silny.

+0

Dzięki za link do "geordi", wygląda imponująco! –

12

Masz rację, że nazwa idzie po *const*. Jeśli podłączyć linię const float *(*const* name)(int) w cdecl.org, powie to, że to znaczy „zadeklarować nazwę jako wskaźnik do const wskaźnik do funkcji (int) powrót wskaźnika do const pływaka

As do parsowania psychicznego, po prostu pamiętać, że R (*p)(A) to wskaźnik do funkcji. Dlatego R (**p)(A) jest wskaźnikiem do wskaźnika do funkcji, a wszystko, co trzeba w tym miejscu, to interakcja.

+1

+1 za nauczanie mnie o cdecl.org – nategoose

+1

++ Za link do cdecl.org – AlcubierreDrive

+0

Dzięki za link cdecl. –

2

Wystarczy pracować z zewnątrz w

Masz coś w postaci:.

U D(V) 

więc masz coś podobnego funkcji.

coś-coś jest funkcją pobierającą int i zwracającą const float*.

Dla (*const*) pracujesz wstecz, aby uzyskać const we właściwym miejscu (chociaż jest to symetryczne, co nie ma tu znaczenia!). *const* ~ "wskaźnik do wskaźnika const na", tak jak (na przykład) w int * const * pp jest wskaźnikiem do wskaźnika const do int.

Łączenie wszystkich razem: wskaźnik do wskaźnika const do funkcji przyjmowania int i zwracanie const float *.

+0

Dzięki! To nie było zbyt skomplikowane. –