Hallo!
Grundsätzlich sind Callback-Funktionen gar nicht so kompliziert.
Allerdings gibt es ein paar feine Unterschiede zwischen den verschiedenen Programmiersprachen, und daher wäre es schon ratsam, wenn du uns zumindest deine Sprache nennst.
Ich versuch’s trotzdem mal selbst:
Dieses Programm:
#include <stdlib.h>
#include <stdio.h>
void myPrinter(int n){
printf("%2d*%2d=%3d\n", n, n, n*n);
}
void myLoop(){
int i;
for (i=1; i<11; i++){
myPrinter(i);
}
}
int main(void){
myLoop();
return 0;
}
gibt die ersten 10 Quadratzahlen auf eine etwas umständliche Art aus:
1* 1= 1
2* 2= 4
3* 3= 9
4* 4= 16
5* 5= 25
6* 6= 36
7* 7= 49
8* 8= 64
9* 9= 81
10*10=100
Bisher ist da noch nichts mit Callback, das baue ich jetzt ein:
#include <stdlib.h>
#include <stdio.h>
void myPrinter(int n){
printf("%2d*%2d=%3d\n", n, n, n*n);
}
void mySecondPrinter(int n){
printf("%2d mal %2d gleich %3d\n", n, n, n*n);
}
void myLoop( void (*ThePrinter)(int) ){
int i;
for (i=1; i<11; i++){
(*ThePrinter)(i);
}
}
int main(void){
myLoop(myPrinter);
myLoop(mySecondPrinter);
return 0;
}
Der erste, einfache Unterschied ist. daß ich eine zweite Funktion für die Ausgabe erstellt habe, die den gleichen Übergabeparameter entgegen nimmt, die Ausgabe aber etwas anders gestaltet.
Etwas komisch ist nun die Zeile void myLoop( void (*ThePrinter)(int) ){
. Diese bedeutet: Die Funktion myLoop
erwartet als Übergabeparameter den Pointer zu einer Funktion, welche ihrerseits ein einzelnes INT als Übergabeparameter erwartet.
Drei Zeilen weiter wird diese Funktion, auf die der Pointer zeigt, mit i
als Parameter aufgerufen.
Nun wurde anfangs die Funktion void myPrinter(int n)
definiert, der Pointer auf diese ist schlicht myPrinter
. Daher steht in der main
dann auch myLoop(myPrinter);
, wodurch diese Funktion angewiesen wird, ihrerseits myPrinter
als Funktion aufzurufen.
Da die Funktion loop
zwei mal aufgerufen wurde und ihrerseits mal die eine, mal die andere Funktion benutzen soll, sieht das Ergebnis so aus:
1* 1= 1
2* 2= 4
3* 3= 9
4* 4= 16
5* 5= 25
6* 6= 36
7* 7= 49
8* 8= 64
9* 9= 81
10*10=100
1 mal 1 gleich 1
2 mal 2 gleich 4
3 mal 3 gleich 9
4 mal 4 gleich 16
5 mal 5 gleich 25
6 mal 6 gleich 36
7 mal 7 gleich 49
8 mal 8 gleich 64
9 mal 9 gleich 81
10 mal 10 gleich 100
Und damit sind wir eigentlich schon fertig. Die Funktion Loop
bekommt eine Funktion übergeben, die sie selbst aufrufen wird, und diese nennt man Callback-Funktion.
In der Realität steckt die Funktion myLoop
beispielsweise in einer Bibliothek, die du zur Verfügung gestellt bekommen hast, und an der du selbst nichts ändern kannst. Die Funktion erzeugt Daten, weiß aber nicht, was damit geschehen soll. Sie erwartet von dir also, eine Callback-Funktion bereitgestellt zu bekommen, die sie aufrufen kann, und genau ein INT erwartet.
Ganz allgemein diktiert die Funktion, was für Übergabeparameter, und in welcher Form (Wert / Pointer) deine Callback-Funktion zu erwarten hat, und das sollte in der Doku stehen.
Ein Grund, warum man das ganze überhaupt macht ist, daß die Funktion die Callback-Funktion auch mehrfach aufrufen kann. Ein häufiger Fall ist auch, daß die Funktion parallel zum eigentlichen Programm läuft, und bei Eintritt bestimmter Ereignisse dann deine Callback-Funktion aufruft. In einem Handy-Spiel könnte z.B. eine Callback-Funktion implementiert sein, die das Spiel anhält, wenn ein Anruf rein kommt. Die App teilt dann am Anfang mit, daß diese Funktion aufgerufen werden soll, wenn ein Anruf rein kommt. Das ist besser, als wenn die App jede Sekunde prüfen muß, ob grade einer anruft…
In anderen Programmiersprachen kommen dann noch andere Feinheiten ins Spiel. In C++ beispielsweise könntest du eine Methode einer Klasse als Callback-Funktion angeben, mußt aber vorher meist eine Instanz von der Klasse erzeugen.
So, das ist schon was länger geworden… Versuche das mal zu verinnerlichen, und wenn du Fragen hierzu, oder zu nem anderen Beispiel im Netz hast, dann frag bitte ganz speziell dazu. Denn häufig betreffen die Fragen auch ein ganz bestimmtes Stück Code, und nichts allgemeines.