Universität Paderborn
Prof. Dr. Heike Wehrheim
Kapitel 1:
Grundlegende
Programmierkonstrukte
1.5 Methoden:
Funktionen und Prozeduren
GPI, WS 07/08
249
Motivation
Universität Paderborn
Prof. Dr. Heike Wehrheim
Bisher:
Weiterbenutzung von einmal geschriebenen
Programmteilen nur durch „copy-and-paste“
Aber:
in größeren Programmen benötigt man dasselbe
Teilprogramm unter Umständen öfters (z.B.
Berechnung einer Wurzel, Sortieren eines Arrays,
…)
Funktionen und Prozeduren (auch: Methoden)
erlauben es, dasselbe Teilprogramm mehrfach zu
verwenden
Funktionen und Prozeduren unterstützen einen
strukturierten Entwurf: erst Algorithmus abstrakt
beschreiben, dann schrittweise konkretisieren
GPI, WS 07/08
250
Schrittweise Verfeinerung
Universität Paderborn
Prof. Dr. Heike Wehrheim
Algorithmen zur Lösung komplexer Fragestellungen müssen
schrittweise entworfen werden.
Zuerst auf abstraktem Niveau festlegen, dann ins Detail
gehen -> Prinzip der schrittweisen Verfeinerung
Veranschaulichung am Kochrezept:
Aufgabenstellung: Menü kochen
Algorithmus abstrakt:
koche Vorspeise
koche Hauptgericht
koche Dessert
dann Teile konkretisieren: am Beispiel koche Dessert
schneide Obst klein
schlage Sahne
mische Obst mit Sahne
GPI, WS 07/08
251
Vorteile
Universität Paderborn
Prof. Dr. Heike Wehrheim
erreicht wird ein hohes Maß an Strukturierung und
Modularisierung der Programme
das erhöht die Lesbarkeit, Wiederverwendbarkeit,
Änderbarkeit, Wartbarkeit, …
Vorlesung „Softwareentwurf“
(dazu trägt übrigens auch die Benutzung von
„sprechenden“ Variablennamen und das Schreiben
von Kommentaren bei!)
… und reduziert meist auch die Anzahl der Fehler!
Java bietet dafür eine Reihe von Konzepten an,
erste nun im folgenden, weitere später.
GPI, WS 07/08
252
Funktionen
Universität Paderborn
Prof. Dr. Heike Wehrheim
Funktionen dienen zur Gliederung von
Programmen.
Eine Funktion soll eine übersichtliche Teilaufgabe
erledigen.
Eine Funktion kann Parameter verwenden, deren
Werte erst im Aufruf angegeben werden.
Eine Funktion berechnet ein Ergebnis und/oder
verändert den Zustand in ihrer Umgebung.
Es können nicht nur vordefinierte Funktionen
verwendet, sondern auch eigene Funktionen
geschrieben werden.
Funktion auch oft: Methode mit Ergebnis
Prozedur: Methode ohne Ergebnis
GPI, WS 07/08
253
Anschauliches Beispiel
Universität Paderborn
Prof. Dr. Heike Wehrheim
Name der Funktion
Ergebnis
Funktionsdefinition:
kocheWasser (x : Liter) -> kochendes Wasser
messe x Liter Wasser ab;
fülle in Wasserkocher;
Parameter
warte bis kocht;
liefere kochendes Wasser ab;
Benutzung (Aufruf):
z.B. kocheWasser(20)
GPI, WS 07/08
254
Funktionsdefinition
Universität Paderborn
Prof. Dr. Heike Wehrheim
Syntax:
Modifizierer Ergebnistyp Funktionsname
(formale Parameter)
Block
Beispiel:
public static double toFahrenheit
(double celsius)
{ return celsius * 9 / 5 + 32; }
public und static sind hier Modifizierer,
andere werden noch später kommen
GPI, WS 07/08
255
Funktionsdefinition II
Ergebnistyp
Name der Funktion
Universität Paderborn
Prof. Dr. Heike Wehrheim
Parameterliste:
Typ und Name
public static int fak (int n) {
Lokale Variable
int ergebnis = 1;
for (int i = 1; i <= n; i++) {
ergebnis = ergebnis * i;
};
return ergebnis;
Bezugnahme auf
}
GPI, WS 07/08
Beenden der Berechnung und
Rückgabe des Ergebnisses
den Wert des
Parameters
256
Funktionskopf
Universität Paderborn
Prof. Dr. Heike Wehrheim
public static int fak (int n)
Definiert die Signatur (Typen der formalen
Parameter und des Ergebnisses der Funktion).
Hier
fak: int -> int
Der Ergebnistyp und die Parametertypen können
beliebige Typen sein (auch Arrays).
Eine Funktion kann beliebig viele Parameter
besitzen, insbesondere auch gar keine.
GPI, WS 07/08
257
Funktionsrumpf
Universität Paderborn
Prof. Dr. Heike Wehrheim
Der Funktionsrumpf legt die Berechnungsvorschrift
fest (ein Anweisungsblock).
Im Funktionsrumpf kann man sich auf die (beim
Aufruf übergebenen) Parameter beziehen. Dazu
benutzt man deren Namen wie Variablen.
Durch die return-Anweisung wird die
Berechnung der Funktion beendet, und der Wert
des Ausdrucks hinter return wird als Ergebnis
zurückgegeben.
Zur Berechnung kann man lokale Variablen
definieren, die beim Beenden der Funktion wieder
„vergessen“ werden.
GPI, WS 07/08
258
Funktionsaufrufe
Universität Paderborn
Prof. Dr. Heike Wehrheim
Funktionsname (aktuelle Parameter);
Die aktuellen Parameter werden ausgewertet und
die Funktion mit den Parameterwerten aufgerufen.
z.B. toFahrenheit(21) ,
toFahrenheit(temp+10),
fak(3*7-4)
Der von der Funktion zurückgegebene Wert kann
normal benutzt werden, also z.B. in Ausdrücken
verwendet werden.
z.B. fahr = toFahrenheit(14);
wert = fak(20 – zahl) + 1;
GPI, WS 07/08
259
Beispiel 1
Universität Paderborn
Prof. Dr. Heike Wehrheim
double a, wurzel;
... // Definition von a
wurzel = Math.sqrt(a + 5.8)*6.7;
// Vordefinierte Wurzelfunktion
GPI, WS 07/08
260
Beispiel 2
Universität Paderborn
Prof. Dr. Heike Wehrheim
double cDegree = 10;
double fDegree;
fDegree = toFahrenheit(cDegree);
System.out.println
(toFahrenheit(cDegree+10));
GPI, WS 07/08
261
Beispiel 3
Universität Paderborn
Prof. Dr. Heike Wehrheim
int zahl = 5;
int ergebnis;
ergebnis = fak(fak(zahl));
oder
Funktionsaufrufe
geschachtelt
ergebnis = fak(5) * fak(zahl);
GPI, WS 07/08
262
Reihenfolge von Parametern
Universität Paderborn
Prof. Dr. Heike Wehrheim
static boolean eineFunktion (int
zahl1,boolean wert,int zahl2) …
boolean b;
int eineZahl, nochEineZahl;
eineFunktion(eineZahl,b,nochEineZahl);
// ok
eineFunktion(eineZahl,nochEineZahl,b);
// nicht ok
eineFunktion(eineZahl,b);
// nicht ok
GPI, WS 07/08
263
Wo hinschreiben?
Universität Paderborn
Prof. Dr. Heike Wehrheim
Beispiel:
public class Fakultaet {
static int fak (int n) {
int ergebnis = 1;
for (int i = 1; i <= n; i++) {
ergebnis = ergebnis * i;
};
return ergebnis;
}
Hier
Funktionsdefinition
public static void main (String [] args) {
int zahl = 5;
int ergebnis = fak(5);
}
Hier
Funktionsaufruf
}
GPI, WS 07/08
264
Weiteres Beispiel – Ausgabe?
Universität Paderborn
Prof. Dr. Heike Wehrheim
class MathFunktion {
static int max (int zahl1, int zahl2) {
if (zahl1 > zahl2)
return zahl1;
else return zahl2;
}
public static void main (String [] args) {
int maximum, ergebnis;
int ersteZahl = 15;
int zweiteZahl = 42;
}}
maximum = max(ersteZahl, zweiteZahl);
System.out.println("Das Maximum ist " + maximum);
ergebnis = max((ersteZahl * 10) + 3,
zweiteZahl - 4);
System.out.println("Das Ergebnis ist " +
ergebnis);
MathFunktion.java
GPI, WS 07/08
265
Eigene Aufgabe
Universität Paderborn
Prof. Dr. Heike Wehrheim
a) Schreiben Sie eine Funktion, die die Differenz von
zwei (int-)Zahlen berechnet.
b) Schreiben Sie eine Funktion, die berechnet, ob
eine Zahl größer 100 ist.
Welche und wieviele Parameter brauchen die
Funktionen?
Was ist jeweils der Ergebnistyp?
GPI, WS 07/08
266
Lösung
Universität Paderborn
Prof. Dr. Heike Wehrheim
static int differenz(int zahl1,
int zahl2) {
return zahl1 – zahl2;
}
static boolean groesserHundert(int
zahl) {
return zahl > 100;
}
GPI, WS 07/08
267
Ausführung von Funktionen
Universität Paderborn
Prof. Dr. Heike Wehrheim
Deklaration:
Modifizierer Ergebnistyp Funktionsname
(formale Parameter) Block
Aufruf:
Funktionsname(aktuelle Parameter)
Zur Ausführung eines Aufrufes wird Speicher angelegt für
die formalen Parameter, das Ergebnis und die lokalen
Variablen der Funktion.
Parameterübergabe „call-by-value“: Die formalen
Parametervariablen werden mit den Werten der
entsprechenden aktuellen Parameter initialisiert.
Eine Anweisung return Ausdruck; beendet den Aufruf
und bestimmt sein Ergebnis. Es können mehrere Return
Anweisungen im Funktionsrumpf stehen. Der Typ des
Ausdrucks hinter return muss dem Ergebnistyp der
Funktion entsprechen.
GPI, WS 07/08
268
Universität Paderborn
Prof. Dr. Heike Wehrheim
Illustration
Call-by-value :
fak
4
n
24
ergebnis Rückgabewert
Bei Aufruf:
4
zahl
• Wert von aktuellem
Parameter zahl
bestimmen
• formalen Parameter
n mit Wert belegen
static int fak (int n) {int ergebnis =
1; … }
…
zahl = 4;
… fak(zahl);
GPI, WS 07/08
269
Universität Paderborn
Prof. Dr. Heike Wehrheim
Illustration II
fak(fak(3))
(jeder Funktionsaufruf hat eigene Kopie der Variablen)
3
n
fak(3)
6
ergebnis
Rückgabewert
6
n
fak(fak(3))
720
ergebnis
GPI, WS 07/08
Rückgabewert
270
Parameterübergabe
Universität Paderborn
Prof. Dr. Heike Wehrheim
Es gibt noch andere Formen der
Parameterübergabe:
call by reference
call by name
Vorlesung GdP (Grundlagen der
Programmiersprachen)
Java benutzt call by value.
GPI, WS 07/08
271
Call-By-Value I
Universität Paderborn
Prof. Dr. Heike Wehrheim
class CallByValueIllustration {
static int minusEins (int zahl) {
zahl--;
return zahl;
}
public static void main (String [] args) {
int eineZahl = 20;
int ergebnis;
ergebnis = minusEins(eineZahl);
System.out.println("Das Ergebnis ist " +
ergebnis);
System.out.println("Der Wert von eineZahl
ist " + eineZahl);
}}
GPI, WS 07/08
CallByValueIllustration.java
272
Call-By-Value II
Universität Paderborn
Prof. Dr. Heike Wehrheim
class CallByValueIllustration2 {
static int minusEins (int zahl) {
zahl--;
return zahl;
}
public static void main (String [] args) {
int zahl = 20;
int ergebnis;
ergebnis = minusEins(zahl);
System.out.println("Das Ergebnis ist " +
ergebnis);
System.out.println("Der Wert von zahl ist " +
zahl);
}}
GPI, WS 07/08
CallByValueIllustration2.java
273
Call-By-Value III
Universität Paderborn
Prof. Dr. Heike Wehrheim
public class CallByValueIllustration4 {
static boolean wertAendern (int [] einArray)
{
einArray[0] = 5;
return true;
}
public static void main (String [] args) {
int [] einIntArray = {1,1,1,1};
boolean b = wertAendern(einIntArray);
System.out.println(einIntArray[0]);
}
}
CallByValueIllustration4.java
GPI, WS 07/08
274
Prozeduren
Universität Paderborn
Prof. Dr. Heike Wehrheim
Prozeduren können eine Änderung ihrer
Umgebung ((Objekt-)Zustand, Ein-, Ausgabe)
bewirken, statt wie eine Funktion ein Ergebnis zu
berechnen.
Sie werden dann als Anweisungen aufgerufen;
keine Benutzung in Ausdrücken.
Statt Ergebnistyp hier void angeben.
Beispiel:
static void hello() {
System.out.println(“Hello World“);
}
GPI, WS 07/08
275
Größeres Beispiel
Universität Paderborn
Prof. Dr. Heike Wehrheim
Man möchte auf dem Zeilendrucker solche Muster
("Tickets") ausdrucken:
=======
=55555=
=55555=
=======
Parameter: Breite in Zeichen (7), Höhe in Zeichen
(4), Innen wiederholtes Zeichen ('5')
Aufruf der Methode
z.B. einTicket(7, 4, '5');
GPI, WS 07/08
276
Benutzung
Universität Paderborn
Prof. Dr. Heike Wehrheim
Bei Aufruf von einTicket (10, 15, '?') entsteht
==========
=????????=
=????????=
=????????=
=????????=
=????????=
=????????=
=????????=
=????????=
=????????=
=????????=
=????????=
=????????=
=????????=
==========
GPI, WS 07/08
277
In Java
Universität Paderborn
Prof. Dr. Heike Wehrheim
Zwei Prozeduren, eine für eine Zeile, eine für das ganze Ticket:
static void eineZeile (int breite, char c)
{
System.out.print ('=');
int i = 2;
while (i < breite)
{
System.out.print (c); i = i+1;
}
System.out.println ('=');
}
static void einTicket (int breite, int höhe, char c)
{
eineZeile (breite, '=');
int i = 2;
while (i < höhe)
{
eineZeile (breite, c); i = i+1;
}
eineZeile (breite, '=');}
TicketDrucker.java
GPI, WS 07/08
278
Gültigkeitsbereiche
Universität Paderborn
Prof. Dr. Heike Wehrheim
Variablendefinitionen gelten vom Ort der Definition
bis zum Ende des Blocks, in dem sie stehen
Block = Folge von Anweisungen in { }
Gültigkeitsbereich, engl. scope
GPI, WS 07/08
279
GPI, WS 07/08
280
args
n
loop
square
public static void main (String []
args) {
int n = 10;
int sum = 0;
int loop = 0;
while (loop < n) {
loop++;
int square = loop * loop;
sum += square;
}
System.out.println(sum);
}
sum
Beispiel
Universität Paderborn
Prof. Dr. Heike Wehrheim
Weiteres Beispiel
Universität Paderborn
Prof. Dr. Heike Wehrheim
}
args
ergebnis
n
zahl
public static void main (String [] args) {
int zahl = 5;
int ergebnis = fak(5);
}
ergebnis
public static int fak (int n) {
int ergebnis = 1;
for (int i = 1; i <= n; i++) {
ergebnis = ergebnis * i;
};
return ergebnis;
}
i
public class Fakultaet {
Zwei verschiedene Variablen ergebnis !
GPI, WS 07/08
281
Fragen I
Universität Paderborn
Prof. Dr. Heike Wehrheim
Sei eine Funktion
static int m(int x) {
x = x + 1;
return x * x;
}
deklariert.
Welchen Wert hat i nach den folgenden
Anweisungen?
a) int i=2; i = m(i) + i;
b) int i=2; i = m(m(i)) + m(i) + i;
GPI, WS 07/08
282
Fragen II
Universität Paderborn
Prof. Dr. Heike Wehrheim
Sei die Methode static void g (int x) { … }
gegeben. Welche Verwendung von g ist
zulässig?
a) int i = g(3);
b) int i = 3; g(i);
c) for (int i = 0; i < 10; g(i) )
{ … }
GPI, WS 07/08
283