C ++ Syntax / Semantik Frage: Verweis auf Funktion und typedef Schlüsselwort

7

Wofür würde typedef int (&rifii) (int, int) verwendet werden?

Was ist der Typedef vor dieser "Anweisung"? Ich möchte das als

betrachten %Vor%

aber der [neue Name] ist nicht da, als wenn du es tust

%Vor%

Ähnliche Frage für die folgende Syntax:

%Vor%

Was erlaubt der Typedef? Mache es so, dass du nicht tippen musst:

%Vor%

Wenn ja, was ist mit dem zweiten Teil ([was Sie wollen]) von typedef wie in:

passiert %Vor%

Die Klärung dieser Angelegenheit wird sehr geschätzt.

    
Matthew Hoggan 01.08.2011, 23:33
quelle

3 Antworten

16

Typedef funktioniert nicht wie typedef [type] [new name] . Der [new name] Teil kommt nicht immer am Ende.

Sie sollten es so betrachten: Wenn [some declaration] eine Variable deklariert, würde typedef [same declaration] einen Typ definieren.

ZB:

  • int x; deklariert eine Variable mit dem Namen x des Typs int - & gt; %Code% definiert einen Typ x als int.
  • typedef int x; definiert eine Variable namens s eines Strukturtyps - & gt; struct { char c; } s; definiert Typ s als einen Strukturtyp.
  • typedef struct { char c; } s; deklariert eine Variable namens p vom Typ Zeiger auf int - & gt; int *p; definiert einen Typ p als Zeiger auf int.

Und auch:

  • typedef int *p; deklariert ein Array von Ints mit dem Namen A - & gt; int A[]; deklariert einen Typ A als ein Array von Ints.
  • typedef int A[]; deklariert eine Funktion namens f - & gt; int f(); deklariert einen Funktionstyp f, der einen int zurückgibt und keine Argumente annimmt.
  • typedef int f(); deklariert einen Funktionsnamen g - & gt; int g(int); deklariert einen Funktionstyp g als Rückgabe eines int und eines int.

Als Nebenbemerkung: Beachten Sie, dass alle Funktionsargumente nach dem neuen Namen kommen! Da diese Typen auch kompliziert sein können, kann nach dem [neuen Namen] viel Text vorhanden sein. Leider, aber wahr.

Aber das sind noch keine richtigen Zeiger , nur Funktionstypen. Ich bin nicht sicher, ob ein Funktionstyp in C oder C ++ existiert, aber es ist als Zwischenschritt in meiner Erklärung nützlich.

Um einen echten Funktionszeiger zu erstellen, müssen wir dem Namen '*' hinzufügen. Was leider einen falschen Vorrang hat:

  • typedef int g(int); deklariert einen Funktionstyp pf als return a int * . Oops, das war nicht das, was beabsichtigt war.

Also benutze () um zu gruppieren:

  • typedef int *pf(); deklariert einen Funktionszeigertyp pf, der ein int zurückgibt und keine Argumente annimmt.
  • typedef int (*pf)(); deklariert einen Funktionsreferenztyp rf, der einen int zurückgibt und keine Argumente annimmt.

Sehen wir uns nun Ihre Beispiele an und beantworten Sie Ihre Fragen:

typedef int (&rf)(); deklariert einen Funktionsreferenztyp rifii, der ein int zurückgibt und zwei int-Argumente annimmt.

Und offensichtlich (?) typedef int (&rifii) (int, int); ruft button2[2]( ); auf.

Korrekte Syntax ohne typedefs ist schwer ohne Compiler zu schreiben und auch mit einem Compiler schwer zu lesen:

%Vor%

Aus diesem Grund bevorzugen alle typedefs bei der Verwendung von Funktionszeigern.

Suchen Sie beim Lesen den Ort, an dem Sie mit dem Lesen beginnen können. Lesen Sie so viel wie möglich nach rechts, aber beobachten Sie die Gruppierung mit (). Lies dann so oft du kannst nach links, wieder begrenzt durch Gruppierung (). Nachdem Sie alles in () abgeschlossen haben, beginnen Sie mit dem Lesen nach rechts und dann nach links.

Angewandt auf copy(); bedeutet dies, dass

  1. edit_ops ist (gehe nach rechts)
  2. ein Array (Klicke auf das Ende der Gruppe, also wende dich nach links)
  3. des Zeigers (Ende der Gruppierung)
  4. zu einer Funktionsaufnahme (parse die () nach rechts)
  5. keine Argumente (gehe nach links)
  6. eine Lücke zurückgeben

Für die Experten: Um es noch komplizierter zu machen, können Argumente Namen haben (die ignoriert werden), so dass es schwierig sein könnte, den Anfang der Analyse zu finden! Z.B. void (*edit_ops[])() ist gültig und dasselbe wie typedef int (*fp)(int x); Namen können sogar () um sie herum haben: typedef int (*fp)(int); Aber wie wir gesehen haben, können Argumentnamen weggelassen werden, so dass auch Folgendes erlaubt ist: typedef int (*fp)(int (x)); . Dies ist immer noch ein Funktionszeiger, der ein einzelnes int und ein int zurückgibt. Falls Sie Ihren Code wirklich schwer lesen möchten ...

    
Sjoerd 02.08.2011, 00:20
quelle
5

Dies:

%Vor%

Erzeugt eine Typdefinition mit dem Namen rifii , eine Funktion, die zwei ganze Zahlen akzeptiert und eine ganze Zahl zurückgibt. Dies ist die typedef-Syntax zum Deklarieren von Funktionstypdefs. Also wenn du eine Funktion hast:

%Vor%

Sie können es in diesem typedef speichern:

%Vor%

Und nenne es später:

%Vor%

Wenn Sie also ein Array von rifii deklarieren, haben Sie ein Array von Referenzen auf Funktionen, die alle die gleiche Signatur haben. Der PF typedef von dir ist eine Zeigerfunktion, die keine Parameter akzeptiert und nichts zurückgibt, also ist ein Array von diesen ein Array von Funktionen, die keine Parameter annehmen und nichts zurückgeben.

Aufgrund der Eigenartigkeit der C / C ++ - Funktionsbenennung wird der typedef-Name (der Name, für den Sie einen typedef-Namen erstellen) in der Mitte des Funktionstyps aufgeführt. Es ist seltsam, aber man gewöhnt sich daran.

    
Nicol Bolas 01.08.2011 23:40
quelle
-1

edit: Sorry, die erste Antwort initialisiert das fcn ptr nicht.

typedef int (& amp; rifii) (int, int) erlaubt Ihnen Funktionszeiger zu deklarieren, die einen int als Referenz zurückgeben und zwei Ints als Parameter verwenden.

%Vor%     
Harry Seward 01.08.2011 23:40
quelle