Jak określa się pierwszeństwo w wskaźnikach C?

14

Natknąłem się na dwie deklaracje wskazujące, które trudno mi zrozumieć. Moje rozumienie zasad pierwszeństwa wygląda mniej więcej tak:

Operator             Precedence             Associativity
(), [ ]                  1                  Left to Right
*, identifier            2                  Right to Left
Data type                3

Ale nawet biorąc to pod uwagę, nie wydaje mi się, aby poprawnie ocenić następujące przykłady:

Pierwszy przykład

float * (* (*ptr)(int))(double **,char c)

Moja ocena:

  1. *(ptr)
  2. (int)
  3. *(*ptr)(int)
  4. *(*(*ptr)(int))

Następnie,

  1. double **
  2. char c

Drugi przykład

unsigned **( * (*ptr) [5] ) (char const *,int *)
  1. *(ptr)
  2. [5]
  3. *(*ptr)[5]
  4. *(*(*ptr)[5])
  5. **(*(*ptr)[5])

Jak powinien ja je czytać?

trapaank
źródło
1
Pytanie o sposób, w jaki język obsługuje jego funkcje, jest na ten temat.

Odpowiedzi:

7

Domyślam się do pierwszego : ptr jest wskaźnikiem do funkcji, która przyjmuje jako parametr int, i zwraca wskaźnik do funkcji, która przyjmuje jako parametry wskaźnik do wskaźnika w celu podwojenia znaku i znaku, i zwraca wskaźnik do wartości zmiennoprzecinkowych.

Interpretacja :

(* ptr) (int)

mówi, że ptr jest wskaźnikiem do funkcji przyjmującej int jako argument. Aby dowiedzieć się, co zwraca ta funkcja, musimy rozszerzyć nasz widok:

(* (* ptr) (int))

oznacza to, że funkcja zwraca wskaźnik do innej funkcji. Parametry tej innej funkcji to:

(double **, char c)

i powraca

pływak *

A po drugie : ptr jest wskaźnikiem do tablicy pięciu wskaźników do funkcji, które przyjmują jako parametry stały wskaźnik do char i wskaźnik do int, zwracając wskaźnik do wskaźnika int bez znaku int.

Interpretacja :

(* (* ptr) [5])

deklaruje ptr jako wskaźnik do tablicy pięciu wskaźników do przejmowania funkcji

(char const *, int *)

jako argumenty i powrót

bez znaku **

Daniel Scocco
źródło
7

Możesz wypróbować metodę „The Clockwise Spiral”, aby zrozumieć te szalone deklaracje:

http://c-faq.com/decl/spiral.anderson.html

Pisałem też o tym tutaj:

http://www.kalekold.net/index.php?post=4

Gary Willoughby
źródło
Dziękuję za odpowiedź. Ale w metodzie The Clockwise Spiral, od czego zacząć w moim przypadku? W przykładach podanych na łączu znajdują się proste przykłady. Nie jestem w stanie dopasować mojego równania do tej metody.
trapaank 21.11.11
1
powinieneś zacząć od swojego identyfikatora: ptr. będziesz mieć: „ptr jest wskaźnikiem do funkcji, która przyjmuje liczbę całkowitą i zwraca wskaźnik do funkcji, która przenosi wskaźnik do wskaźnika do znaku podwójnego i znaku, a zwraca wskaźnik do liczby zmiennoprzecinkowej”. spróbuj spyral, a dostaniesz to samo.
Remo.D
1

To wskaźnik funkcji. Osoba, która to napisała, mogłaby lepiej wykorzystać typedefs, aby było to bardziej zrozumiałe.

W efekcie jest to wskaźnik do działania z tymi parametrami. float * myfunc (double **, char)

Michael Shaw
źródło
4
Założę się, że osoba, która to napisała, jest nauczycielem.
mouviciel
Miejmy nadzieję, że to nie nauczyciel, bo nie musisz znać takich bzdur. Chociaż przypuszczam, że dobry nauczyciel najpierw uderzyłby cię w twarz takimi wyrazami twarzy, co pozwoliłoby ci podrapać się w głowę, próbując je zinterpretować, a następnie pokazać, jak prawidłowo pisać na maszynie.