> Also Fehlermeldung gibts keine - aber woher weiß ich den das der
> pointer auf ein Funktion ein "int" lang ist ? - oder inerpretiere
ich
> den typedef falsch ?
Jep, tust du.
Kurze Erklärung:
Die ints im typedef sagen nur etwas über die Signatur der Funktion aus,
auf die der Zeiger zeigt.
Lange Erklärung:
Das typedef sieht ja so aus:
typedef int (*fptr)(int);
Lassen wir mal das * weg und nennen fptr in f um:
typedef int (f)(int);
Die Klammern um f kann man sich dann natürlich auch schenken:
typedef int f(int);
So, das sieht nun beinahe wie ein ganz gewöhnlicher Funktionsprototyp
aus, abgesehen vom typedef davor.
Der Typ f bezeichnet hier eine Funktion selbst, keinen Zeiger darauf.
Dieser Typ ist damit genauso abstrakt wie void, man kann keine Variable
vom Typ f erstellen. Was man aber darf, ist folgendes:
f* p;
p ist jetzt ein Zeiger auf eben die Funktion, deren Prototyp
("Signatur") ich oben "getypedeft" habe.
Man kann nun also ohne weiteres die beiden letzen Zeilen kombinieren:
typedef int f(int);
typedef f* fptr;
Damit deklariert man den Typ fptr unmissverständlich als
Funktionszeiger. Jetzt möchte man aber gerne nur ein typedef haben,
also wird eingesetzt:
typedef int (int)* fptr; /* oberes typedef stur ins untere eingesetzt
*/
Das ist aber totaler Blödsinn, die Parameter gehören immer ans Ende:
typedef int * fptr (int);
Aber halt! Gerade eben noch hatten wir:
typedef int f(int);
als abstraktes Funktionsobjekt definiert. Was ist jetzt
typedef int* fptr (int);
für den Compiler? Natürlich genauso ein abstraktes Funktionsobjekt. Nur
diesmal liefert die so spezifierte Funktion einen int* zurück.
Aus genau diesem Grund muss man so ungewohnte Klammern setzen:
typedef int (*fptr)(int);
Jetzt muss auch der letzte Compiler akzeptieren, dass man hier einen
Zeiger deklariert, kein abstraktes Funktionstypedef. Und zwar einen
Zeiger auf eine Funktion, die a) einen int zurückliefert und b) einen
int übernimmt.
Funktionszeiger sind in C (und in C++ noch stärker) ein völlig eigener
Typ. Funktionszeiger werden in C++ (und ich denke auch in C) strikt von
Datenzeigern getrennt behandelt.
char*, int*, das sind alles Datenzeiger. void* ist in diesem Sinne aber
auch ein Datenzeiger und damit nicht kompatibel zu Funktionszeigern.
Funktionszeiger können nämlich größer sein als void* (in C++ sind sie
es auch häufig).
In C könnte es z.B. passieren, dass du eine Maschine hast, die viel
mehr Programmspeicher als RAM hat. Dann hat ein void* vielleicht nur 16
Bit, ein Funktionszeiger aber 24 (rein hypothetisch). Das wäre mit dem
C-Standard ohne weiteres vereinbar, führt bei unsauberer Programmierung
aber schnell zu Fehlern.
Einen Funktionszeiger speichert man daher korrekterweise niemals in
einem void*.
Ein int muss sowieso nicht groß genug für einen Zeiger sein, egal ob
Daten- oder Funktionszeiger. Bei 64-Bit-Rechnern etwa hat ein int immer
noch 32 Bit, ein Zeiger aber 64 Bit (beim Visual C++ Compiler).