Wie wird die Priorität in C-Zeigern bestimmt?

14

Ich habe zwei Zeigererklärungen gefunden, bei denen ich Probleme mit dem Verständnis habe. Mein Verständnis der Vorrangregeln sieht ungefähr so ​​aus:

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

Aber trotz alledem kann ich nicht herausfinden, wie man die folgenden Beispiele richtig bewertet:

Erstes Beispiel

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

Meine Bewertung:

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

Dann,

  1. double **
  2. char c

Zweites Beispiel

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

Wie soll ich sie lesen?

Trapaank
quelle
1
Die Frage, wie eine Sprache mit ihren Funktionen umgeht, ist hier ein Thema.

Antworten:

7

Meine Vermutung für die ersten : ptr ein Zeiger auf eine Funktion , die als Parameter einen int nimmt, und gibt einen Zeiger auf eine Funktion , die als Parameter einen Zeiger auf Zeiger nimmt zu verdoppeln und ein char, und gibt einen Zeiger zu schweben.

Interpretation :

(* ptr) (int)

sagt, dass ptr ein Zeiger auf eine Funktion ist, die ein int als Argument verwendet. Um herauszufinden, was diese Funktion zurückgibt, müssen wir unsere Ansicht erweitern:

(* (* ptr) (int))

Dies bedeutet, dass die Funktion einen Zeiger auf eine andere Funktion zurückgibt. Die Parameter dieser anderen Funktion sind:

(double **, char c)

und es kehrt zurück

float *

Und für die zweite : ptr ist ein Zeiger auf ein Array von fünf Zeigern auf Funktionen, die einen konstanten Zeiger auf char und einen Zeiger auf int als Parameter verwenden und einen Zeiger auf einen Zeiger von int ohne Vorzeichen zurückgeben.

Interpretation :

(* (* ptr) [5])

deklariert ptr als Zeiger auf ein Array von fünf Zeigern auf eine Funktion, die nimmt

(char const *, int *)

als Argumente und zurück

ohne Vorzeichen **

Daniel Scocco
quelle
7

Sie können die Methode 'Die Spirale im Uhrzeigersinn' ausprobieren, um diese wahnsinnigen Erklärungen zu verstehen:

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

Ich habe auch hier darüber gebloggt:

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

Gary Willoughby
quelle
Danke für deine Antwort. Aber bei der Methode "Spirale im Uhrzeigersinn", von wo aus ich in meinem Fall anfangen soll? In den Beispielen auf dem Link gibt es einfache Beispiele. Ich bin nicht in der Lage, meine Gleichung mit dieser Methode abzugleichen.
Trapaank
1
Sie sollten mit Ihrem Bezeichner beginnen: ptr. Sie werden haben: "Ptr ist ein Zeiger auf eine Funktion, die ein Int nimmt und einen Zeiger auf eine Funktion zurückgibt, die einen Zeiger auf einen Zeiger auf ein Double und ein Char nimmt und einen Zeiger auf ein Float zurückgibt". Probieren Sie den Spyral und Sie werden das gleiche bekommen.
Remo.D
1

Es ist ein Funktionszeiger. Die Person, die es geschrieben hat, hätte typedefs besser nutzen können, um es klarer zu machen.

Es ist praktisch ein Zeiger, um mit diesen Parametern zu arbeiten. float * myfunc (double **, char)

Michael Shaw
quelle
4
Ich wette, die Person, die es geschrieben hat, ist der Lehrer.
mouviciel
Hoffen wir, dass es nicht der Lehrer ist, weil Sie so etwas nicht wissen müssen. Obwohl ich nehme an, ein guter Lehrer würde Ihnen mit solchen Ausdrücken zuerst ins Gesicht schlagen und Sie sich beim Versuch, sie zu interpretieren, den Kopf kratzen lassen und Ihnen dann zeigen, wie man typedef richtig verwendet.