Funktionen Zusammenfassung von Befehlssequenzen als aufrufbare/wiederverwendbare Funktionen in einem Programmblock mit festgelegter Schnittstelle (Signatur) Derartige prozedurale Programmierung erlaubt Dekomposition komplexer Probleme Im Folgenden: Definition von Funktionen Deklaration vs. Definition Parameterübergabe Pass by Value Pass by Reference Defaults, Overloading, variable Parameteranzahl Rekursion Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 68
Funktionen: Definition Syntax zur Definition einer Methode [<Speicherklasse>] <Typ> <Funktionsname>(<Parameterliste>) { <Anweisungen> } Wichtigste Speicherklassen static: Funktion kann nur innerhalb dieser Quelldatei benutzt werden extern (Default): Funktion kann aus anderen Quelldateien benutzt werden, speziellextern C undextern C++ für Benutzung aus C- bzw. C++-Programmen inline: Quelltext der Funktion kann als Optimierung an aufrufender Stelle direkt eingesetzt werden, Empfehlung für den Compiler Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 69
Funktionen: Rückgabetyp Funktionen haben einzelnen typisierten Rückgabewert, da Funktionsaufrufe dadurch einfach Ausdrücke sind Bisher: Rückgabewerte von einfachen Basisdatentypen Alternativen zur Modifikation von mehreren Variablen bzw. komplexerer Ergebnisdaten Pass by Reference (Veränderung der Parametervariablen ) Ergebnis als Feld oder selbstdefinierter komplexer Typ (z.b. struct ) Zeiger auf Feld oder komplexen Datentyp ( ) oderclass ) Wenn kein sinnvoller Rückgabewert existieren kann, spezieller Typvoid, zum Beispiel void ausgabe(char* text) { printf( %s, text);} wobei entsprechende Methoden keinreturn benötigen Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 70
Funktionen: Deklaration Deklaration einer Funktion entspricht deren Bekanntmachung, d.h. Funktion existiert, Implementierung ist aber an einer anderen Stelle [<Speicherklasse>] <Typ> <Funktionsname>(<Parameterliste>); Auch Signatur bzw. Prototyp der Funktion Erlaubt Verwendung der Funktion im Quelltext, auch wenn noch keine Implementierung angegeben wurde Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 71
Funktionen: Deklaration /2 Gebräuchliche Anwendungen Vorab-Deklaration einer Funktion, die schon im Quelltext benutzt wird, deren Implementierung aber erst an späterer Stelle folgt (zwingend erforderlich z.b. wenn Funktionen sich gegenseitig aufrufen, aber in einer bestimmten Reihenfolge im Quelltext definiert werden müssen) Deklaration von Methoden in Header-Dateien, deren Implementierung aus anderen Quelldateien erst später vom Linker hinzugefügt wird Deklaration von Methoden (Klassenfunktionen) in einer Klassendefinition (in der Regel auch in Header-Dateien) Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 72
Vorab-Deklaration: Beispiel (C++) /1 #include <iostream> using namespace std; void ungerade(int z); void gerade(int z) { if (z%2==0) cout << Zahl ist gerade. << endl; else ungerade(z); } void ungerade(int z) { if (z%2!=0) cout << Zahl ist ungerade. << endl; else gerade(z); }... Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 73
Vorab-Deklaration: Beispiel (C++) /2... int main() { int x; cout << x = ; cin >> x; gerade(x); return 0; } Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 74
Funktionen: Übergabe von Parametern Bisher: Parameter können an eine Funktion als literale Werte oder Werte einer Variable übergeben werden float add(float a, float b) { return a+b; }... float x,y,z;... x = add(32.3,9.7); // literale Werte x = add(y,z); // Variablenwerte Werte werden dazu in die Speicherbereiche der lokalen Variablen der Funktion kopiert 1. Aufruf:aerhält Wert 32.3,berhält Wert 9.7 2. Aufruf:aerhält Wert vony,berhält Wert vonz Werte vonyundzbleiben unverändert Pass by Value (auch Call by Value) Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 75
Funktionen: Pass by Value oder by Reference Pass by Value: Übergabe der Parameter durch Kopieren der Werte, wodurch eine Modifikation der ursprünglichen Variablen ausgeschlossen wird Pass by Reference: Übergabe einer Referenz auf die Ursprungsvariable, wodurch deren Wert in der Funktion manipuliert werden kann C und C++ bieten unterschiedliche Möglichkeiten zur Umsetzung von Pass by Reference, welche in C++ beide verwendet werden können C und C++: Übergabe von referenzierter Variable als Zeiger auf Speicherbereich der Variable nur C++: Übergabe als spezielles Referenzparameter, d.h. lokale Parametervariable der Funktion ist anderer Name der Ursprungsvariablen vom Funktionsaufruf Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 76
Pass by Reference: C-style Basiert auf der Übergabe von Zeigerwerten statt eigentlichen Datenwerten Zeiger ( ) oder auch Pointer von einem bestimmten Typ entsprechen Speicheradresse an dem ein Wert von diesem Typ steht Entsprechende Deklaration der Methode mit Zeigerparametern, z.b. void tausche(int* x, int* y) {... } Beim Aufruf mit normalen Variablen muss vorher die Adresse jeder Variable berechnet werden tausche(&a,&b); Technik bisher schon verwendet, z.b. beiscanf() ausstdio zum Einlesen von Werten für Variablen Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 77
Einschub: Beispiel für Arbeit mit Zeigern int i = 13; i ist normale Variable mit Wert 13 an Adressex int* p; p ist undefinierter (!) Zeiger (Pointer) aufint-wert p = &i; Referenzierung (Bildung eines Zeigers auf Adresse der dahinter stehenden Variable) mit&, p zeigt jetzt auf Adresse x *p = 7; Dereferenzierung mit*, Wert an Adressexist jetzt 7 *p==7 && i==7; Ist jetzt wahr... Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 78
Pass by Reference: C-Style Beispiel (C++)... void tausche(int* x, int* y) { int hilfe = *x; *x = *y; *y = hilfe; } int main() { int a=4; int b=7; cout << Vorher: a= << a << b= << b << endl; tausche(&a,&b); cout << Nachher: a= << a << b= << b << endl; return 0; } Vorher: a=4 b=7 Nachher: a=7 b=4 Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 79
Pass by Reference: C++-style C++ führt Konzept der Referenzvariablen und Referenzparameter durch speziellen Syntax bei der Deklaration mit&ein: entsprechend deklarierte Variablen sind anderer Name für eine zuvor definierte Variable Entsprechende Deklaration der Methode mit Referenzparametern, z.b. void tausche(int& x, int& y) {... } Erlaubt einfache Übergabe von Variablen ohne weitere Transformation tausche(a,b); Kritik an C++-Lösung: beim Aufruf einer Funktion ist im Quelltext an dieser Stelle nicht mehr ersichtlich, ob die übergebenen Variablen verändert werden könnten erfordert Kenntnis über Funktionsdefinition/-deklaration Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 80
Pass by Reference: Beispiel (C++) #include <iostream> using namespace std; void tausche(int& x, int& y) { int hilfe = x; x = y; y = hilfe; } int main() { int a=4; int b=7; cout << Vorher: a= << a << b= << b << endl; tausche(a,b); cout << Nachher: a= << a << b= << b << endl; return 0; } Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 81
Funktionen: mehr zu Parametern Defaultwerte für Parameter können bei Funktionsdefinition angegeben werden Parameter kann beim Aufruf weggelassen werden char* zahl_als_string(int zahl, basis b=10) {... } Overloading (Überladen) erlaubt Funktionen mit gleichem Namen aber unterschiedlichen Parametern (passende Implementierung wird vom Compiler nach Typ der Parameter beim Aufruf ausgewählt) char* zahl_als_string(int zahl) {... } char* zahl_als_string(float zahl) {... } Variable Parameterzahl in einer Funktionsdefinition durch... umsetzbar (erfordert aber spezielle Behandlung der Liste von Parametern mit beliebigen Datentypen), verwendet z.b. bei printf(char* format,...); Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 82
Funktionen: Rekursion Definition (Rekursion) Rekursion (vom lateinischen recurrere: zurückführen, zurücklaufen) bezeichnet die Technik, eine Funktion durch sich selbst zu definieren. In der Programmierung: Funktionen können direkt oder indirekt (über eine weitere Funktion) sich selbst aufrufen Konzept entliehen aus der funktionalen Programmierung, im Gegensatz zu imperativer Programmierung als nur Folge von Befehlen Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 83
Funktionen: Rekursion Anwendbar für viele Aufgaben: Berechnungsmöglichkeiten äquivalent zu Schleifen Rekursion kann Schleifen immer ersetzen bzw. von diesen ersetzt werden Vorteile: Oft einfache, elegante Lösungen möglich Praktisch zum Beispiel bei komplexeren Datenstrukturen (z.b. wenn diese rekursiv definiert sind: Hierarchien, Bäume), Optimierung, etc. Nachteile: Funktionsaufrufe verursachen erhöhten Aufwand bei der Programmausführung Performance Führt mitunter zu komplexeren Programmstrukturen, die schwerer verständlich bzw. deren Korrektheit schwerer verifizierbar ist Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 84
Rekursion: Beispiel Fakultätsberechnung Mathematische Funktion für natürlich Zahlen n n! = 1 2 3 4 n = n i i=1 Kann so als Schleife (Zählschleife mit Produktbildung) umgesetzt werden Aber auch rekursive Definition möglich: { 1 n = 0 n! = n (n 1)! n > 0 Umsetzbar als rekursive Funktion Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 85
Rekursion: Beispiel (C++) #include <iostream> using namespace std; int fakultaet(int i) { if (i<=1) return 1; else return i*fakultaet(i-1); } int main() { int x,f; cout << x = ; cin >> x; f = fakultaet(x); cout << x! = << f << endl; return 0; } Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 86
Rekursion: Beispiel - Ablauf Ergebnis: 4*6=24 Aufruf fakultaet( 4) Ergebnis: 3*2=6 Aufruf fakultaet( 3) Aufruf Ergebnis: 2*1=2 fakultaet( 2) Ergebnis: 1 Aufruf fakultaet( 1) Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 87
Zusammenfassung: Funktionen Funktionen als wiederverwendbare, zusammenhängende Folge von Anweisungen zur Strukturierung des Quelltextes Definition einer Funktion mit Speicherklasse, Rückgabetyp, Name, Parameter und deren Typen sowie eigentlicher Implementierung als Programmblock Deklaration einer Funktion als Bekanntmachung der Schnittstelle erlaubt Benutzung im Quelltext, ohne dass Implementierung bis dahin gegeben Parameterübergabe als kopierte Werte (Pass by Value) oder modifizierbare Variablen (Pass by Reference) Rekursion als spezielles Programmierparadigma für Funktionen erlaubt direkten oder indirekten Aufruf der Methode durch sich selbst Eike Schallehn Grundlagen der Informatik für Ingenieure 2009/2010 4 88