Prozeduren und Funktionen - fbi.h

Werbung
FB Informatik
Prof. Dr. R.Nitsch
Prozeduren und Funktionen
Reiner Nitsch
℡ 8417
[email protected]
www.fbi.h_da.de/~r.nitsch
Wozu Prozeduren/Funktionen?
FB Informatik
Prof. Dr. R.Nitsch
• Verbergen von Implementierungsdetails bzw. Komplexität
– Abstraktion dient dazu, Komplexität zu verstecken
– Prozeduren/Funktionen sind ein Mittel der Abstraktion (man interessiert sich nicht mehr
für bestimmte Details, vereinfacht die Realität). Hier spielt es für den Benutzer/Aufrufer
keine Rolle,
• wie die Prozedur/Funktion ihre Aufgabe löst, sondern nur
Prozedurale Abstraktion
• was sie genau macht.
Input
?
Output
Prozedur/Funktion als
Black-Box-Abstraktion
• Strukturierung von Code
– Programme können beliebig lang sein (Spaghetti-Code, schwer zu verstehen, schlecht
wiederverwendbar)
– Oft braucht man im gleichen Programm an verschiedenen Stellen ein gleiches Stück
Programmcode (Bsp: Menüs anzeigen, Grafikobjekte zeichnen, Textdateien einlesen, … ).
– Um die Lesbarkeit & Änderbarkeit& Übersichtlichkeit des Programms zu verbessern, sollte
dieser Programmcode nur einmal aufgeschrieben werden.
– Das ist mit Prozeduren/Funktionen möglich:
• Man kann einem Stück Programmcode einen Namen geben, und es dann an verschiedenen
Stellen im Programm aufrufen (ausführen lassen).
30.03.2009
2
Wozu Prozeduren/Funktionen?
FB Informatik
Prof. Dr. R.Nitsch
• Delegation von Teilaufgaben
– Zerlegen einer komplexen Aufgabe in mehrere, einfacher lösbare Teilaufgaben
(Teile und Herrsche) und Delegation dieser Teilaufgaben an
Prozeduren/Funktionen (Programming by delegation)
• Wiederverwendung von Code
– Mehrere solcher Prozeduren bzw. Funktionen mit gleichem Focus werden oft zu
Klassen, Modulen, Bibliotheken zusammengefaßt (z.B. Grafikbibliothek,
Mathematische Bibliothek, C++ Standardbibliothek, … )
• Vorteile solcher Bibliotheken: Die Wiederverwendung bereits getesteter
Funktionen
– spart Zeit und Geld
– verkürzt die time-to-market und
– verbessert die Zuverlässigkeit neuer Software.
30.03.2009
3
Anforderungen an Prozeduren und Funktionen
FB Informatik
Prof. Dr. R.Nitsch
• Sollten nur für eine genau definierte Aufgabe zuständig sein.
• müssen bei Bedarf einen oder mehrere Eingabewerte (Eingabeparameter)
übernehmen können
– Sie dienen der Übermittlung von Werten aus dem aufrufenden Programm an die
Proz./Fkt.
• Sollten nicht mehr als die unbedingt nötigen Eingabeparameter erwarten.
• Sollten Ergebnisse bei Bedarf zurückgeben können.
– Funktionen haben genau einen Rückgabewert.
• Er dient der Übermittlung eines Wertes (Ergebnis) aus der Funktion an das
aufrufende Programm
• Funktionen können daher in Ausdrücken dort eingesetzt werden, wo ein Wert
erwartet wird.
– Prozeduren haben keinen Ausgabewert und können daher nicht in Ausdrücken für
einen Wert stehen. Sie werden stets in einer einzelnen Anweisung aufgerufen.
• Sollten gut dokumentiert sein (Aufgabe, Vorbedingungen, Nachbedingungen)
• Minimale Abhängigkeit vom Rest des Programms durch
– möglichst kleine/einfache Schnittstelle zum Rest des Programms.
• In Prozeduren/Funktionen kann man auch selbst wieder Prozeduren/Funktionen
aufrufen.
30.03.2009
4
Bestandteile eines C++ Programms
FB Informatik
Prof. Dr. R.Nitsch
Bestandteile eines C++ Programms
Kern von C++
Standardtypen
Operatoren
Kontrollstrukturen
Klassen und
Prozeduren/Funktionen
der Standardbibliothek
Selbsterstellte Klassen
und Prozeduren/Funktionen
und weitere Bibliotheken
C++ kennt keine keine spezielle Syntax für Prozeduren.
In C++ sind Prozeduren einfach Funktionen ohne Ausgabewert.
30.03.2009
5
Globale benutzerdefinierte Funktion ohne Parameter
#include <iostream>
using namespace std;
void main () {
// show menu
cout << "[1] Eingabe\n";
cout << "[2] Ausgabe\n";
cout << "[9] Fertig\n";
// …
}
Wird mehrmals im
Programm verwendet.
cut&paste Nachteile?
void steht für "kein Rückgabewert"
#include <iostream>
namespace std;
void showMenu();
void main() {
showMenu();
// …
}
Funktionsname
besser mit
Funktionsaufruf
Funktionsdeklaration oder
Funktionsprototyp
Funktionsaufruf
Funktionskopf
void showMenu()
{
cout << "[1] Eingabe\n";
cout << "[2] Ausgabe\n ";
cout << "[9] Fertig\n";
return;
}
30.03.2009
Funktionsdefinition
Funktionsrumpf
FB Informatik
Prof. Dr. R.Nitsch
• Die Funktiondeklaration (Fkt-Prototyp)
beschreibt das Funktionsinterface. Sie
enthält für den Compiler alle erforderlichen Angaben (Typ, Reihenfolge und
Menge der Ein- und Ausgabewerte), um den
Funktionsaufruf übersetzen zu können.
Merke:
• Eine Funktion muss vor der ersten
Benutzung deklariert aber nicht
definiert sein.
• Eine Funktion kann überall und
beliebig oft deklariert werden.
• Die Definition kann dann hinter main
am Ende der Datei oder in einer ganz
anderen Datei (z.B. Library) stehen.
• Die Funktionsdefinition (Implementierung)
sagt dem Compiler, wie die Funktion ihre
Aufgabe erledigen soll.
• In C++ können Funktionen nicht innerhalb
anderer Funktionen definiert werden.
• Die einmal übersetzte Funktionsdefinition
wird nach jedem Aufruf ausgeführt.
6
Globale Funktion mit Parametern und mit/ohne Rückgabewert
FB Informatik
Prof. Dr. R.Nitsch
Um die Funktionsdeklarationen nicht in jeder Anwendung neu eintippen zu müssen, werden Sie in
Header-Dateien (*.h) zusammengefaßt und diese Header-Dateien von der Anwendung inkludiert.
#include <iostream>
using namespace std;
Typ des Rückgabewerts
Typ des Parameters
double getCircleArea( double radius
Formalparameter; hier nur 1 Parameter
);
Variablenspeicher
Parametername (optional; zur Dokumentation)
int main()
lokale Variable der Funktion main
{
Stapelspeicher
r
2.0
double r = 2.0;
(Stack)
cout << getCircleArea(r) << endl;
area
12.56
Kopie
return 0;
radius
2.0
}
Aktualparameter
12.56
Rückgabewert
Funktionswert
…
Formalparameter
Name hier zwingend!
(Eingangstür zur Fkt.)
double getCircleArea(double radius ) {
double area;
area = 3.14 * radius * radius;
return area;
}
Lokale Variable (Name optional) der Funktion
getCircleArea (lokale Variable, d.h. im Hauptprogramm
main nicht bekannt und nicht zugreifbar)
Kopie
Ausgangstür der Funktion. Nicht die lok. Variable area wird hier
zurückgegeben, sondern die Kopie ihres Wertes im Stack
30.03.2009
7
Ablauf eines Funktionsaufrufs
FB Informatik
Prof. Dr. R.Nitsch
…
weitere lokale Parameter
Beim Rücksprung
"poppen"
letzter Parameter
…
1. Parameter
Beim Aufruf
"pushen"
Stack (Stapelspeicher)
oder LIFO (Last In First Out)
Funktionswert
Rücksprungadresse
• Reservierung von Speicherplatz auf dem Stapelspeicher (stack) für die FormalParameter. Initialisierung der Formal-Parameter mit den Aktual-Parametern
(Argumenten).
• Speichern der Rücksprungadresse (= Stelle des Funktionsaufrufes im Programm)
auf dem Stack und Fortsetzung des Programms am Anfang der aufgerufenen
Funktion.
• Nach Ausführung der Funktion, Fortsetzung des Programms in der aufrufenden
Funktion mit Hilfe der gesicherten Rücksprungadresse. Freigabe des belegten
Stacks.
30.03.2009
8
Benutzung von Bibliotheksfunktionen
FB Informatik
Prof. Dr. R.Nitsch
// Calculation of powers xy with function pow( double x, double y )
#include <iostream>
#include <cmath>
// Hinzufügen aller Funktionsdeklarationen der math-Library
using namespace std;
int main()
double x
y = pow(
y = pow(
y = pow(
{
= 1.5, y;
x, 3.0 );
x, 3 );
x, 2+1 );
y = pow( "x", 3);
y = pow( x + 3 );
cout << y << endl;
return 0;
}
// ok! return-Wert an y zuweisen
// auch ok! Typkonversion int → double durch Compiler
// Auch ok! Als Parameterwert darf auch ein beliebiger Ausdruck übergeben werden
// Aber Anzahl und Typ der Parameter müssen passen!
// Fehler: Typkonflikt
// Fehler: nur 1 Parameter
// Ausgabe: 3.375 = 1.53
Woher weiß der Compiler Anzahl und
Typ der erwarteten Parameter ?
// cmath enthält die Deklaration
double pow( double x, double y );
30.03.2009
9
Struktur eines C++ Programms
FB Informatik
Prof. Dr. R.Nitsch
Programmkopf
Präprozessor-Direktiven (z.B. #include)
Deklaration von globalen Objekten
Funktionsdeklarationen (i.A. in Header-Dateien)
Klassendeklarationen (i.A. in Header-Dateien)
Implementierung
int main()
{
// Variablendefinitionen …
// Ausführbare Anweisungen …
return 0;
}
Klassenimplementierung
Funktionsimplementierung
30.03.2009
10
HS-Übung 1
FB Informatik
Prof. Dr. R.Nitsch
• Finden Sie die Fehler in den folgenden Programmfragmenten und erklären Sie, wie
der Fehler behoben werden kann.
a) int g(void) {
cout << "in Funktion g\n";
int h(void){
cout << "in Funktion h\n";
}
}
c) void f(double a){
float a;
cout << a << endl;
}
30.03.2009
b) int sum( int x, int y){
int result ;
result = x+y;
}
d) void product (void){
int a, b, c, ergebnis;
cout << "Gib 3 Ganzzahlen ein: ";
cin >> a >> b >> c;
result = a * b * c;
cout << "Ergebnis: << result << endl;
return result;
}
11
HS-Übung 2
FB Informatik
Prof. Dr. R.Nitsch
• Definieren Sie eine Funktion, welche die Seitenlängen eines Quaders übergeben
bekommt und das Volumen des Quaders zurück gibt. Integrieren Sie den
Funktionsaufruf in die nachfolgende Anwendung. Geben Sie das Ergebnis auf dem
Bildschirm aus.
//Zweck: Berechnung des Quadervolumens
#include <iostream>
using namespace std;
int main (void){
double a, b, c;
cout << "Gib die Seitenlaengen eines Quaders: ";
}
30.03.2009
13
Zusammenfassung: Prozeduren / Funktionen
FB Informatik
Prof. Dr. R.Nitsch
•
•
•
•
•
•
•
•
lösen eine abgeschlossene Teilaufgabe,
erbringen Leistungen, die mehrmals im Programm anfallen (können),
müssen vor erstmaligem Aufruf deklariert (oder implementiert) werden,
verursachen einen geringen Laufzeitverlust beim Aufruf,
können (in C++) nicht innerhalb anderer Funktionen definiert werden,
verbergen Implementationsdetails vor dem Anwender,
erleichtern die Wiederverwendung von Code,
sollten genau umrissene Einzelaufgaben lösen, die sich in der Namensgebung
wiederspiegeln. Kleine Funktionen unterstützen die Wiederverwendbarkeit.
• sind die Bausteine, aus denen C-Programme bestehen,
• müssen in C++ innerhalb von Klassen ( -> Memberfunktionen) oder global definiert
sein, d.h. Funktionsdefinitionen dürfen nicht verschachtelt sein.
30.03.2009
14
Herunterladen