13
Prof. Dr. Nikolaus Wulff Programmieren in C Programmieren in C Zeiger auf Funktionen

Programmieren in C - · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 3 Zeiger auf Funktionen • Ein Funktionszeiger wird deklariert als: • Wichtig ist die Klammer bei der

Embed Size (px)

Citation preview

Page 1: Programmieren in C - · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 3 Zeiger auf Funktionen • Ein Funktionszeiger wird deklariert als: • Wichtig ist die Klammer bei der

Prof. Dr. Nikolaus Wulff

Programmieren in CProgrammieren in C

Zeiger auf Funktionen

Page 2: Programmieren in C - · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 3 Zeiger auf Funktionen • Ein Funktionszeiger wird deklariert als: • Wichtig ist die Klammer bei der

Prof. Dr. Nikolaus Wulff Programmieren in C 2

Zeiger auf Funktionen

• Zeiger verweisen auf beliebige Speicherstellen.

• Im Allgemeinen werden Zeiger ausgerichtet auf Variablen, wie z. B. Strukturen oder Felder. D. h. der Zeiger verweist auf den Datenbereich.

• Es ist jedoch auch möglich einen Zeiger auf die Adresse einer Funktion verweisen zu lassen.

• Mit Hilfe eines solchen Zeigers lässt sich dann eben diese Funktion aufrufen.

• Diese Zeiger lassen sich auch als Argumente an andere Funktionen übergeben.

Page 3: Programmieren in C - · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 3 Zeiger auf Funktionen • Ein Funktionszeiger wird deklariert als: • Wichtig ist die Klammer bei der

Prof. Dr. Nikolaus Wulff Programmieren in C 3

Zeiger auf Funktionen

• Ein Funktionszeiger wird deklariert als:

• Wichtig ist die Klammer bei der Deklaration eines Function Pointers:

• Nur die letzte Variante ist ein Funktionszeiger.

int *f; /* Zeiger auf ein int */

int *f(); /* Funktion mit Rückgabe int-Zeiger */

int (*f)(); /* Zeiger auf Funktion mit Rückgabe int */

<return_type> (*ptr_name)(<arg_liste>)

Page 4: Programmieren in C - · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 3 Zeiger auf Funktionen • Ein Funktionszeiger wird deklariert als: • Wichtig ist die Klammer bei der

Prof. Dr. Nikolaus Wulff Programmieren in C 4

FunctionPointer

• Die Deklaration eines Zeigers auf eine Funktion (FunctionPointer) sieht auf dem ersten Blick etwas gewöhnungsbedürftig aus:

– (*fct) ist ein Zeiger auf eine reelwertige Funktion mit double Variablen und Rückgabewert, z.B. sin(x).

– (*subr) ist ein Zeiger auf eine Methode ohne Argumente und Rückgabewert.

– (*cmp) ist ein Zeiger auf eine Funktion mit einem int als Rückgabewert und zwei Argumenten vom Typ void* .

double (*fct)(double x);void (*subr)(void);int (*cmp)(void *px,void *py);

Page 5: Programmieren in C - · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 3 Zeiger auf Funktionen • Ein Funktionszeiger wird deklariert als: • Wichtig ist die Klammer bei der

Prof. Dr. Nikolaus Wulff Programmieren in C 5

Auswertung eines FP's

• Die Methode printFctAt soll den Wert einer beliebigen Funktion zum Argument x ausgeben:

• fct ist der Zeiger auf eine beliebige (reelwertige) Funktion,

• x ist das Argument der Funktion.

• printf wertet fct(x) mit Argument x aus ...

void printFctAt(double(*fct)(double), double x) { printf("Funktion(%f) = %f \n", x, fct(x));

}

Zeiger auf die Funktion

Page 6: Programmieren in C - · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 3 Zeiger auf Funktionen • Ein Funktionszeiger wird deklariert als: • Wichtig ist die Klammer bei der

Prof. Dr. Nikolaus Wulff Programmieren in C 6

Typedef auf FunctionPointer

• Mit einem typedef lässt sich die Schreibweise für einen FunctionPointer elegant vereinfachen:

• Ebenso wie „normale Zeiger“ können nun auch Zeiger auf Funktionen als Variablen und eigene Typen verwendet werden.

/** * Declare a real valued Function. */typedef double (*Fct)(double x);/** * Prototyp for printFctAt. */void printFctAt(Fct f, double x);

Page 7: Programmieren in C - · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 3 Zeiger auf Funktionen • Ein Funktionszeiger wird deklariert als: • Wichtig ist die Klammer bei der

Prof. Dr. Nikolaus Wulff Programmieren in C 7

Verwendung von printFctAt

• Die Verwendung zeigt, das prinfFctAt ganz universell beliebige Funktionen auswerten kann...

void printFctAt(double(*fct)(double), double x) { printf("Funktion(%f) = %f \n", x, fct(x));}

double square(double x) { return x*x;}

void main() {

double x; x = 3.14/4; printfFctAt(cos, x); /* cos from <math.h> */ printfFctAt(square ,x); /* self made function */ ...

Funktion wirdausgewertet

Page 8: Programmieren in C - · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 3 Zeiger auf Funktionen • Ein Funktionszeiger wird deklariert als: • Wichtig ist die Klammer bei der

Prof. Dr. Nikolaus Wulff Programmieren in C 8

Numerische Differentiation

• Mit Hilfe eines Funktionszeigers soll eine Methode zum Ableiten beliebiger stetig differentierbarer Funktionen entwickelt werden.

• Ausgangspunkt ist die Definition der Ableitung als Grenzübergang:

• Formal kann dieser Grenzübergang approximiert werden durch eine Folge immer kleinerer h-Werte.

• Die Frage ist, wie klein muss/darf h werden?

f ' x =dfdx

=limh0f xh− f x

h

Page 9: Programmieren in C - · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 3 Zeiger auf Funktionen • Ein Funktionszeiger wird deklariert als: • Wichtig ist die Klammer bei der

Prof. Dr. Nikolaus Wulff Programmieren in C 9

Numerische Differentiation (II)

• Anleihe bei der Taylor-Reihe (Mathe II):

• Subtraktion beider Gleichungen liefert für kleine h

• Jetzt ist eine Abschätzung des Fehlers möglich. Für z.B. h=0.001 ist der Fehler in der Größenordnung 0.0000001 mal der dritten Ableitung von f.

f xh= f x h f ' x h2

2f ' ' x O h3

f x−h= f x −h f ' x h2

2f ' ' x −O h3

f ' x ≈f xh− f x−h

2h±O h2

Page 10: Programmieren in C - · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 3 Zeiger auf Funktionen • Ein Funktionszeiger wird deklariert als: • Wichtig ist die Klammer bei der

Prof. Dr. Nikolaus Wulff Programmieren in C 10

/** * Differentiate any given Function at point x. * @param f: function to differentiate * @param x: double the argument where to differentiate * @return: double with the value of f'(x) */double differentiate(double (*f)(double), double x) { double h = 0.0001; return (f(x+h)-f(x-h))/(2*h);}

void main() { double x; for(x = 0;x < 1; x+=0.1) { printf("x=%f sin=%f, cos=%f, f'= %f\n", x, sin(x), cos(x), differentiate(sin,x)); }}

Differentiation einer Funktion

x=0.200000 sin=0.198669, cos=0.980067, f'= 0.980067x=0.300000 sin=0.295520, cos=0.955336, f'= 0.955336

Ausgabe:

Page 11: Programmieren in C - · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 3 Zeiger auf Funktionen • Ein Funktionszeiger wird deklariert als: • Wichtig ist die Klammer bei der

Prof. Dr. Nikolaus Wulff Programmieren in C 11

FP für eigene Funktionentypedef double (*Fct)(double x);

double xsquare(double x) { return x*x;}

void main() { double x; Fct fct; /* FP as variable */

fct = sin; /* sin from <math.h> */ for(x = 0;x < 1; x+=0.1) { printf("x=%f sin=%f f'= %f\n", x, sin(x),differentiate(fct,x)); } fct = xsquare; /* self defined... */ for(x = 0;x < 1; x+=0.1) { printf("x=%f x^2=%f f'= %f\n", x, xsquare(x),differentiate(fct,x)); }}

x=0.400000 x^2=0.160000 f'= 0.800000Ausgabe:

Page 12: Programmieren in C - · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 3 Zeiger auf Funktionen • Ein Funktionszeiger wird deklariert als: • Wichtig ist die Klammer bei der

Prof. Dr. Nikolaus Wulff Programmieren in C 12

Callback Methoden

• Funktionszeiger und Strukturen werden häufig in graphischen Fenstersystemen verwendet, um sogenannte Callback-Methoden zu implementieren.

• Beispiel: Ein Button muss beim Drücken eine bestimmte Funktionalität ausführen.

• Der Entwickler der Button Routine weiß jedoch nicht in welchem Kontext der Button verwendet wird.– Einmal ist damit ein FileOpenDialog assoziert, ein

anderes Mal die Auswahl einer Farbe oder Schrift etc.

• Wie lässt sich ein solch unterschiedliches Verhalten realisieren?

Page 13: Programmieren in C - · PDF fileProf. Dr. Nikolaus Wulff Programmieren in C 3 Zeiger auf Funktionen • Ein Funktionszeiger wird deklariert als: • Wichtig ist die Klammer bei der

Prof. Dr. Nikolaus Wulff Programmieren in C 13

Buttons und Menus

• Die GUI Elemente sind Strukturen mit Platzhaltern für entsprechende Callback Methoden.

• Beim Betätigen eines Buttons wird die jeweilige Callback-Methode aufgerufen und die dahinter codierte Funktionalität ausgeführt.

typedef void (*Callback)(ActionEvent evt);

typedef struct button_struct { char* text; Callback action;} Button;

typedef struct menu_struct { char* text; Callback action;} Menu;