Kapitel 1 - Universität Paderborn

Werbung
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
Herunterladen