2015-08-03 8 views
5

Ich lese C++ in einfachen Schritten und stieß auf ein Stück Code für Referenzen und Zeiger, die ich nicht verstehe.Deklaration in C++

Der Code lautet void (* fn) (int& a, int* b) = add;. Soweit ich weiß, hat dies keine Auswirkungen auf das Programm selbst, möchte aber wissen, was dieser Code tut.

#include <iostream> 
using namespace std; 

void add (int& a, int* b) 
{ 
    cout << "Total: " << (a+ *b) << endl; 
} 

int main() 
{ 
    int num = 100, sum = 200; 
    int rNum = num; 
    int* ptr = &num; 

    void (* fn) (int& a, int* b) = add; 

    cout << "reference: " << rNum << endl; 
    cout << "pointer: " << *ptr << endl; 

    ptr = &sum; 
    cout << "pointer now: " << *ptr << endl; 
    add(rNum, ptr); 
    return 0; 
} 
+1

[Heres] (http://cdecl.org/) eine sehr gute Website für Erklärungen. Es hat jedoch Probleme mit diesem. – yizzlez

+0

Dieser Befehl weist die Variable 'fn', einen Zeiger auf Funktion, den Wert eines Zeigers auf die Funktion' add' zu. 'fn' wird später nicht verwendet und die Zuweisung ist im Wesentlichen nutzlos. –

+0

@awesomeyi Da Referenzen nicht in C sind, können Sie auch die Argumente in den Deklarationen dort nicht benennen. – Barry

Antwort

11

die Spirale Regel verwenden:

 +----------------------+ 
    | +--+    | 
    |^|    | 
void (* fn) (int& a, int* b) = add; 
^ |  |    | 
| +-----+    | 
+---------------------------+ 

fn ist ein Zeiger auf eine Funktion, zwei Argumente (ein int& genannt a und eine int* genannt b) und void Zurücknahme. Der Funktionszeiger ist eine Kopie, die mit der freien Funktion add initialisiert wurde.

Also, wo in Ihrem Code Sie haben:

add(rNum, ptr); 

Das gleichwertig ersetzt werden könnte:

fn(rNum, ptr); 
+0

Danke, ich verstehe, wie es jetzt funktioniert. –

+0

Es gibt hier keine Zuweisung, und selbst wenn es gäbe, würde "hinzufügen" zu "fn" zugewiesen und nicht umgekehrt. –

+0

Richtig, blätterte die Wörter in meinem Kopf. Fest. – Barry

4

Wenn Sie lesen über the clockwise/spiral rule die Erklärung einfach zu entziffern:

Sie Deklarieren Sie eine Variable fn, die ein Zeiger ist, zu einer Funktion, die einige Argumente nimmt und nichts zurückgibt.

Dann machen Sie diese Funktion Zeiger fn Punkt auf die add Funktion.

Sie können dann den Funktionszeiger verwenden, anstatt add direkt aufzurufen.

7

fn ist ein Zeiger auf eine Funktion, die von links nach rechts eine int& und eine int* nimmt, die nichts zurückgibt.

Sie sind zuweisen die Funktion add zu fn.

Sie könnte rufen Sie die Funktion add durch den Zeiger, indem genau die gleiche Syntax wie würden Sie, wenn Sie den Einsatz add waren.

Eine Verwendung dieser Technik ist in der Modellierung von Rückruf Funktionen. Beispielsweise benötigt qsort eine Rückruffunktion für das Sortierprädikat. Funktionszeiger sind häufiger in C als in C++, wo es andere Techniken wie Funktionsobjekte, Vorlagen, Lambdas und sogar std::function gibt.

3

void (* fn) (int& a, int* b) = add; erklärt ein function pointerfn benannt, die Punkte, die Punkte auf eine Funktion, die eine Signatur von void(int&,int*) hat. Es infiltriert dann den Zeiger auf die add() Funktion.

1

Solche komplizierten Deklarationen können leicht mit der right-left rule gelesen werden, die sogar funktioniert, wenn the clockwise spiral rule fails, die auch im Falle von etwas so einfach wie int* a[][10] tut.

void (* fn) (int& a, int* b); 

beginnt mit der Kennung fn und geht von rechts nach links, mit den Klammern, die Richtung Spiegeln. So ist fn ein Zeiger auf eine Funktion, die sich auf int und einen Zeiger auf int beziehen, und der Rückgabetyp der Funktion ist void.

Es heißt Lesen :) Siehe this answer für ein anderes Beispiel.