Anweisung - an der HTWG Konstanz

Werbung
Programmiertechnik
Kontrollstrukturen
Prof. Dr. Oliver Haase
Oliver Haase
Hochschule Konstanz
1
Was sind Kontrollstrukturen?
 Kontrollstrukturen erlauben es, ein Programm nicht nur Zeile für
Zeile auszuführen, sondern in Abhängigkeit bestimmter
Bedingungen bestimmte Programmteile auszuführen.
 Siehe z.B. folgende (Kontroll-)Flussdiagramme:
Anweisung
Bedingung?
Entscheidung
false
Anweisung
Bedingung?
true
Schleife
false
true
Anweisung
Anweisung
Anweisung
Anweisung
Anweisung
Anweisung
Anweisung
Anweisung
Oliver Haase
Hochschule Konstanz
2
Überblick
 Kontrollstrukturen steuern den Ablauf eines Programms.
 Kontrollstrukturen sind spezielle Arten von Anweisungen.
 In Java (wie in den meisten Programmiersprachen) gibt es
verschiedene Arten von Anweisungen:
 Deklarationsanweisungen
 Zuweisungsanweisungen
 Methodenaufruf
 Blöcke
 If-Anweisungen
 Switch-Anweisungen
 Schleifen
 Sprünge
Oliver Haase
hier behandelt
Hochschule Konstanz
3
Blöcke
 Ein Block ist eine mit { und } geklammerte Folge von Anweisungen.
 Ein Block kann überall dort wo eine Anweisung erlaubt/erfordert ist,
als eine einzige Anweisung eingesetzt werden.
 Innerhalb eines Blocks können auch Variablen deklariert werden,
deren Gültigkeit auf den Block beschränkt ist.
int i = 1;
{
}
{
}
Oliver Haase
int j = 2;
System.out.println(i +j);
Blöcke
int j = 3;
System.out.println(i +j);
Hochschule Konstanz
4
If-Anweisung
Die If-Anweisung ist die fundamentalste aller Kontrollanweisungen
Syntaxregel
if (<Bedingung>)
<Anweisung>
else
<Anweisung>
 <Bedingung> ist ein Ausdruck, der ein Ergebnis vom Typ boolean
liefert, z.B. boolsche Variable, logische Operation, oder Vergleich.
 Auswertung:
 <Bedingung>
 falls <Bedingung> true liefert, dann unmittelbar folgende Anweisung
 falls <Bedingung> false liefert, dann Anweisung unmittelbar nach
else.
Oliver Haase
Hochschule Konstanz
5
If-Anweisung
 Beispiel Betragsberechnung:
double x, y;
java.util.Scanner scanner =
new java.util.Scanner(System.in);
System.out.print("x:");
x = scanner.nextDouble();
if (x < 0.0)
y = -x;
else
y = x;
System.out.println("Der Betrag von " + x + " ist " + y);
 Merke: Nur die Anweisung unmittelbar nach else gehört zum
'Sonst'-Fall, die Bildschirmausgabe nicht mehr!
Oliver Haase
Hochschule Konstanz
6
If-Anweisung
 Der else-Teil kann komplett fehlen:
Syntaxregel
if (<Bedingung>)
<Anweisung>
 Beispiel Betragsberechnung 2:
double x, y;
java.util.Scanner scanner =
new java.util.Scanner(System.in);
System.out.print("x:");
x = scanner.nextDouble();
y = x;
if (x < 0.0)
y = -x;
System.out.println("Der Betrag von " + x + " ist " + y);
Oliver Haase
Hochschule Konstanz
7
If-Anweisung
 Die Anweisungsteile können selbst Blöcke sein. Damit ergibt sich
die Form:
Syntaxregel
if (<Bedingung>) {
<Anweisung>
…
<Anweisung>
}
else {
<Anweisung>
…
<Anweisung>
}
Oliver Haase
Hochschule Konstanz
8
If-Anweisung
 Es ist guter Stil, selbst einzelne Anweisungen zu klammern, um
Fehler zu vermeiden (defensives Programmieren).
 Siehe folgendes Beispiel. Was ist hier falsch?
int x = scanner.nextInteger();
if (x == 0) {
System.out.println("x ist gleich 0");
}
else
System.out.println("x ungleich 0, wir dividieren");
System.out.println("1/x liefert " + 1 / x);
Oliver Haase
Hochschule Konstanz
9
Switch-Anweisung
 Ebenso wie die If-Anweisung eine Entscheidungsanweisung.
 Erlaubt, in verschiedene Alternativen zu verzweigen
Syntaxregel
switch (<Ausdruck>) {
case <Konstante>:
<Anweisungsfolge>
break;
…
case <Konstante>:
<Anweisungsfolge>
break;
default:
<Anweisungsfolge>
}
Oliver Haase
Hochschule Konstanz
10
Switch-Anweisung
 <Ausdruck> muss byte, short, int, oder char liefern.
 Wenn Auswertung von <Ausdruck> den Wert <Konstante>
liefert, wird die entsprechende <Anweisungsfolge> ausgeführt.
 Beachte: <Anweisungsfolge>, im Unterschied zu einem Block, muss
nicht geklammert werden!
 Wenn Wert von Ausdruck nicht gefunden wird, wird
<Anweisungsfolge> hinter default-Marke ausgeführt.
 Die default-Marke kann fehlen, dann wird im obigen Fall gar
nichts ausgeführt.
Oliver Haase
Hochschule Konstanz
11
Switch-Anweisung
 Beispiel:
char result;
// result wird ein Character zugewiesen
switch (result) {
case '+':
System.out.println("gutes Ergebnis");
break;
case '-':
System.out.println("schlechtes Ergebnis");
break;
case 'o':
System.out.println("So-la-la-Ergebnis");
break;
default:
System.out.println("unbekanntes Ergebnis");
}
Oliver Haase
Hochschule Konstanz
12
Switch-Anweisung
 Wenn break-Anweisung fehlt, wird die Ausführung fortgesetzt
bis ein break erreicht wird  engl: Fall-Through.
 Praktisch, wenn mehrere Werte denselben Effekt haben sollen:
char result;
// result wird ein Character zugewiesen
switch (result) {
case 'o':
case '+':
System.out.println("bestanden");
break;
case '-':
System.out.println("durchgefallen");
break;
default:
System.out.println("unbekanntes Ergebnis");
}
Oliver Haase
Hochschule Konstanz
13
Switch-Anweisung
 Ein vergessenes break ist aber auch eine häufige Fehlerursache:
int a, b;
a = scanner.nextInteger();
switch (a) {
case 1:
b = 10;
case 2:
case 3:
b = 20;
break;
default:
b = 40;
}
Welchen Wert erhält b für verschiedene Werte von a?
Oliver Haase
Hochschule Konstanz
14
Schleifen
 Schleifen erlauben es, eine Anweisung (einen Block von
Anweisungen) mehrmals zu durchlaufen.
 Java kennt 3 Arten von Schleifen:
 For-Schleifen
 While-Schleifen
 Do-Schleifen
 Allen Schleifenarten ist gemeinsam, dass sie eine
Abbruchbedingung enthalten.
Oliver Haase
Hochschule Konstanz
15
For-Schleife
Syntaxregel
for (<Initialisierung>; <Bedingung>; <Update>)
<Anweisung>
Auswertung:
1. Mit Hilfe der <Initialisierung> wird eine Schleifenvariable deklariert
und initialisiert, z.B. int i = 0
2. Die <Bedingung>, die üblicherweise die vorher initialisierte Variable
enthält, wird ausgewertet. Beispiel: i < 10
3. Falls Schritt 2 false ergibt, wird die Schleife beendet
4. Falls Schritt 2 true ergibt, wird
a)
b)
c)
<Anweisung> ausgeführt
<Update> ausgeführt, z.B. i++
mit Schritt 2 fortgefahren
Oliver Haase
Hochschule Konstanz
16
For-Schleife
 Auswertung als Kontrollflussdiagramm:
Initialisierung
Bedingung?
false
true
Anweisung
Update
Oliver Haase
Hochschule Konstanz
17
For-Schleife
 Beispiel:
for ( int i = 0; i < 10; i++ )
System.out.println("i: " + i);
 <Anweisung> -- der Schleifenrumpf – kann ein geklammerter
Block von Anweisungen sein.
 Ebenso wie bei der If-Anweisung ist es guter Stil, den
Schleifenrumpf immer zu klammern. (Warum?)
Oliver Haase
Hochschule Konstanz
18
For-Schleife
 Jeder Bestandteil des Schleifenkopfs (Initialisierung, Bedingung,
Update) kann fehlen
 keine Bedingung → entspricht true
 Beispiel
int i = 0;
for ( ; i < 10; ) {
System.out.println("i: " + (i++));
}
Oliver Haase
Hochschule Konstanz
19
For-Schleife
 Der geklammerte Anweisungsblock im Schleifenrumpf kann
selbst wieder eine Schleife sein:
for ( int i = 0; i < 10; i++ ) {
for ( int j = 0; j < i; j++ ) {
System.out.println("(" + i + ", " + j + ")");
}
}
Oliver Haase
Hochschule Konstanz
20
While-Schleife
 Die While-Schleife ist allgemeiner (flexibler) als die For-Schleife.
Syntaxregel
while (<Bedingung>)
<Anweisung>
Auswertung:
1. <Bedingung> wird ausgewertet
2. Falls Auswertung false ergibt, wird die Schleife beendet
3. Falls Auswertung true ergibt, wird
a)
b)
Oliver Haase
<Anweisung> ausgeführt
mit Schritt 1 fortgefahren
Hochschule Konstanz
21
While-Schleife
 Auswertung als Kontrollflussdiagramm:
Bedingung?
false
true
Anweisung
Oliver Haase
Hochschule Konstanz
22
While-Schleife
 Natürlich kann der Schleifenrumpf ein geklammerter Block von
Anweisungen sein.
 Bei der While-Schleife muss der Programmierer die
Schleifenvariable ggf. selbst deklarieren, initialisieren und im
Schleifenrumpf aktualisieren. Beispiel:
int i = 0;
while ( i < 10 ) {
System.out.println("i: " + i);
i++;
}
 Auch hier ist es guter Stil, den Schleifenrumpf immer zu
klammern!
Oliver Haase
Hochschule Konstanz
23
While-Schleife
 Jede For-Schleife kann durch eine While-Schleife ersetzt werden.
for (<Initialisierung>; <Bedingung>; <Update>)
<Anweisung>
<Initialisierung>;
while (<Bedingung>) {
<Anweisung>;
<Update>;
}
Oliver Haase
Hochschule Konstanz
24
Do-Schleife
 Ähnlich wie While-Schleife, nur dass Bedingung erst nach
Ausführung des Rumpfs getestet wird  Schleife wird mindestens
einmal durchlaufen.
Syntaxregel
do
<Anweisung>
while (<Bedingung>);
Auswertung:
1.
2.
3.
4.
<Anweisung> wird ausgeführt
<Bedingung> wird ausgewertet
Falls Auswertung false ergibt, wird die Schleife beendet
Falls Auswertung true ergibt, wird mit Schritt 1 fortgefahren
Oliver Haase
Hochschule Konstanz
25
Do-Schleife
 Auswertung als Kontrollflussdiagramm:
Anweisung
Bedingung?
false
true
Oliver Haase
Hochschule Konstanz
26
Do-Schleife
 Natürlich kann der Schleifenrumpf ein geklammerter Block von
Anweisungen sein.
 Genauso wie bei der While-Schleife muss der Programmierer
die Schleifenvariable selbst deklarieren, initialisieren und im
Schleifenrumpf aktualisieren. Beispiel:
int i = 0;
do {
System.out.println("i: " + i);
i++;
} while ( i < 10 );
 Auch hier ist es guter Stil, den Schleifenrumpf immer zu
klammern!
Oliver Haase
Hochschule Konstanz
27
Do-Schleife
 Jede Do-Schleife kann durch eine While-Schleife ersetzt werden.
do
<Anweisung>
while (<Bedingung>);
<Anweisung>;
while (<Bedingung>)
<Anweisung>;
Oliver Haase
Hochschule Konstanz
28
Endlosschleife
 Wenn die Schleifenbedingung niemals false ergibt, liegt eine
Endlosschleife vor.
 Endlosschleifen können absichtlich, aber auch versehentlich
programmiert werden.
 Beispiel für absichtliche Endllosschleife:
while (true) {
System.out.println("Nochmal!");
}
Oliver Haase
Hochschule Konstanz
29
Endlosschleife
 Unabsichtliche Endlosschleifen resultieren meist daraus, dass
vergessen wird die Schleifenvariable im Schleifenrumpf zu verändern.
 Beispiel für unabsichtliche Endllosschleife:
int i = 0;
while (i < 10) {
System.out.println("i: " + i);
}
Oliver Haase
Hochschule Konstanz
30
Sprünge
 In Java gibt es keine goto-Anweisung!
 Es gibt nur zwei eingeschränktere Sprungvarianten, nämlich:
 break  um eine Schleife (oder eine Switch-Anweisung) zu verlassen
 continue  um zur Schleifenbedingung zu springen
Oliver Haase
Hochschule Konstanz
31
Break




Bereits zusammen mit Switch-Anweisung kennengelernt
Springt aus innerster Schleife
Wird meistens verwendet, um Schleife vorzeitig zu verlassen.
Beispiel:
int product = 1;
for ( int i = 1; i < 20; i++) {
product *= i;
if ( product > 1000000 ) {
break;
}
}
System.out.println(product);
Oliver Haase
Hochschule Konstanz
32
Break
 Merke: break kann immer durch geeignete Schleifenbedingung
ersetzt werden!
 Beispiel:
int i = 1;
int product = 1;
do {
product *= i;
i++;
} while ((i < 20) & ( product <= 1000000));
System.out.println(product);
Oliver Haase
Hochschule Konstanz
33
Continue
 Springt zum innersten Schleifenkopf
 Sinnvoll, um Schleifenausführung für bestimmte Sonderfälle zu
vermeiden.
 Beispiel:
for ( int i = -10; i <= 10; i++ ) {
if ( i == 0 ) {
continue;
}
System.out.println("1/" + i + "= " + 1/i);
}
Oliver Haase
Hochschule Konstanz
34
Herunterladen