Programmierkurs Kapitel 5 Kontrollstrukturen Arten von

Werbung
Kapitel 5
Programmierkurs
Kontrollstrukturen
Die if-Anweisung
Die switch-Anweisung
Die for-Schleife
Die while-Schleife
Die do-Schleife
Birgit Engels, Anna Schulze
ZAIK
Universität zu Köln
WS 07/08
1 / 55
Kontrollstrukturen
2
Arten von Kontrollstrukturen
Bis jetzt wurden in jedem Programm alle Befehle nacheinander
einmal ausgeführt:
Das Programm machte (bis auf unterschiedliche Eingabewerte)
immer das gleiche.
Bedingte Ausführung
◮
◮
if/if ... else-Anweisung
switch-Anweisung
(Bedingte) Mehrfachausführung
Sogenannte “Kontrollstrukturen” sind besondere Anweisungen, die
es einem Programm ermöglichen, sich unterschiedlich zu verhalten
oder Befehlsabfolgen mehrfach auszuführen.
◮
◮
◮
3 / 55
for-Schleife
while-Schleife
do ... while-Schleife
4
5.1 Die if-Anweisung
Beispiel für if: IfElse.java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
if ( < Bedingung > ) < Anweisung >
oder
if ( < Bedingung > ) < Anweisung 1 > else
< Anweisung 2 >
< Bedingung > ist ein Wert ∈ {true, false}, eine Variable vom Typ
boolean oder ein boolscher Ausdruck, der zu einem solchen Wert
ausgewertet wird.
Anweisung ist eine einzelne Anweisung oder ein Block von
Anweisungen.
Im ersten Fall wird die Anweisung nur ausgeführt, wenn die
Bedingung den Wert true hat.
Im zweiten Fall wird die Anweisung1 ausgeführt, wenn die
Bedingung den Wert true hat.
Andernfalls wird Anweisung2 ausgeführt.
public static void main(String[] args)
{
boolean b=true, d=false;
int a=1, c=1;
if (b) b=false;
if (!b) System.out.println(‘‘b=false’’);
if (a>c) System.out.println(‘‘a>c’’);
else System.out.println(‘‘a<c oder a=c’’);
if (a==c) System.out.println(‘‘a=c’’);
if (b=d) System.out.println(‘‘b=d’’);
}
b=false
a<c oder a=c
a=c
5 / 55
Beispiel für if: IfElse.java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Beispiel für if: IfElse.java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
public static void main(String[] args)
{
boolean b=true, d=false;
int a=1, c=1;
if (b) b=false;
if (!b) System.out.println(‘‘b=false’’);
if (a>c) System.out.println(‘‘a>c’’);
else System.out.println(‘‘a<c oder a=c’’);
if (a==c) System.out.println(‘‘a=c’’);
if (b=d) System.out.println(‘‘b=d’’);
}
b=false
a<c oder a=c
a=c
6
Bedingung liefert Wert true: Anweisung wird ausgefürt.
7 / 55
public static void main(String[] args)
{
boolean b=true, d=false;
Auswertung von “a>b” liefert Wer
int a=1, c=1;
false: Anweisung wird nicht aus
if (b) b=false;
gefürt.
if (!b) System.out.println(‘‘b=false’’);
if (a>c) System.out.println(‘‘a>c’’);
else System.out.println(‘‘a<c oder a=c’’);
if (a==c) System.out.println(‘‘a=c’’);
if (b=d) System.out.println(‘‘b=d’’);
}
b=false
a<c oder a=c
a=c
Statt dessen wir die else-Anweisung
ausgefürt.
8
Beispiel für if: IfElse.java
Beispiel 2 für if: BlockIfElse.java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
public static void main(String[] args)
{
boolean b=true, d=false;
int a=1, c=1;
if (b) b=false;
if (!b) System.out.println(‘‘b=false’’);
if (a>c) System.out.println(‘‘a>c’’);
else System.out.println(‘‘a<c oder a=c’’);
if (a==c) System.out.println(‘‘a=c’’);
if (b=d) System.out.println(‘‘b=d’’);
Fehler: Anstelle einer Bedingung ei}
ne Zuweisung. Geht nur bei boolschen
Werten, da Wert der Zuweisung gelieb=false
fert wird. Wert ist false: Anweisung
a<c oder a=c
wird nicht ausgefürt.
a=c
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
public static void main(String[] args)
{
int a=3, b=4, min, max;
if (a<b) {
min=a;
max=b; }
else {
min=b;
max=a; }
System.out.println(‘‘min= ’’+min+‘‘ max= ’’+max);
}
min= 3 max= 4
9 / 55
Beispiel 2 für if: BlockIfElse.java
10
Häufige Fehler bei if
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
public static void main(String[] args)
{
int a=3, b=4, min, max;
if (a<b) {
min=a;
max=b; }
else {
min=b;
max=a; }
Zuweisungen von min und max wird
System.out.println(‘‘min= ’’+min+‘‘ max= ’’+max);
durch Block zu einer Anweisung. In}
nerhalb solcher Blöcke können auch
weitere if-Anweisungen auftreten.
min= 3 max= 4
11 / 55
if (a<b)
{
min=a;
max=b;
}
else
min=b;
max=a;
if (a<b);
min=a;
Kein Block im else-Teil : Als
else-Anweisung gilt nur min=b;:
max=a; wird immer ausgeführt (vgl.
NoBlockIfElse.java).
Abschluss nach if-Bedingung mit ;:
leere if-Anweisung und min=a; wird
immer ausgeführt.
12
Beispiel 3 für if: MoreIfElse.java
1.
2.
3.
4.
5.
6.
7.
Beispiel 3 für if: MoreIfElse.java
1.
2.
3.
4.
5.
6.
7.
public static void main(String[] args)
{
int a=1, b=2;
if (a<b) System.out.println(‘‘a<b’’);
else if (a>b) System.out.println(‘‘a>b’’);
else System.out.println(‘‘a=b’’);
Verschachtelte if- Anweisung mit
}
else if: Z.B. als Fallunterscheidung.
a<b
public static void main(String[] args)
{
int a=1, b=2;
if (a<b) System.out.println(‘‘a<b’’);
else if (a>b) System.out.println(‘‘a>b’’);
else System.out.println(‘‘a=b’’);
}
a<b
13 / 55
Fallunterscheidungen mit else if
14
5.2 Die switch-Anweisung
switch (< Ausdruck >)
{
case < Wert1 > : < Anweisung >; break;
case < Wert2 > : < Anweisung >; break;
...
default : < Anweisung >; break; }
char c=’x’;
int ascii;
if (c==’a’) ascii=97;
else if (c==’b’) ascii=98;
...
else if (c==’z’) ascii=122;
else ascii=0;
< Ausdruck >: arithmetischer Ausdruck oder einzelne
Variable.
Fallunterscheidungen mit else if sind bei vielen Fällen
unkomfortabel und enthalten den Overhead der
Vergleichsbedingung. Für solche Anwendungen verwendet man
daher die switch- Anweisung.
< Wert >: Wert, den < Ausdruck > annehmen kann.
< Anweisung >: einzelne Anweisungen Block von
Anweisungen.
Die Anweisungen hinter default werden ausgeführt, falls
< Ausdruck > keinen der < Wert >e annimt.
15 / 55
16
switch vs. else if
Beispiel für switch: AsciiSwitch.java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Die Zeile
case < Wert > : < Anweisung >; break;
einer switch-Anweisung entspricht in etwa der Zeile:
(else) if (< Ausdruck >==< Wert >) <
Anweisung >;
einer else if-Anweisung.
Die Zeile
default : < Anweisung >; break;
einer switch-Anweisung entspricht der letzten Zeile:
else < Anweisung >;
// einer else
if-Anweisung.
public static void main(String[] args)
{
char c=’e’;
int ascii;
switch (c) {
case ’a’: ascii=97; break;
case ’b’: ascii=98; break;
...
case ’z’: ascii=122; break;
default: ascii=0; break;
}
System.out.println(ascii);
}
Nur im default-Fall darf break; weggelassen werden.
101
17 / 55
Beispiel für switch: AsciiSwitch.java
18
Beispiel für switch: AsciiSwitch.java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
public static void main(String[] args)
{
char c=’e’;
int ascii;
switch (c) {
case ’a’: ascii=97; break;
case ’b’: ascii=98; break;
...
case ’z’: ascii=122; break;
default: ascii=0; break;
}
Wichtig: Erst break; schliesst einen
System.out.println(ascii);
case ab. Ohne break; werden weite}
re Anweisungen ausgeführt!
101
19 / 55
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
...
switch (c) {
case ’a’: ascii=97; break;
...
case ’e’: ascii=101;
case ’f’: ascii=102; break;
...
case ’z’: ascii=122; break;
default: ascii=0; break;
}
...
102
20
Beispiel für switch: AsciiSwitch.java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Bemerkung zu break
...
switch (c) {
case ’a’: ascii=97; break;
...
case ’e’: ascii=101;
case ’f’: ascii=102; break;
...
case ’z’: ascii=122; break;
default: ascii=0; break;
}
Vergessenes break;: Nächste Anwei...
sungen ausgeführt - Falscher Wert!
Es kann natürlich auch sinnvoll sein, einen Fall einer
switch-Anweisung nicht mit break; abzuschliessen.
Z.B.: Wenn in 2 Fällen die gleiche Anweisung folgen soll oder im
ersten Fall nur zusätzliche Anweisungen zuvor auszuführen sind.
Da ein weggelassenes break nur der Bequemlichkeit dient, ein
vergessenes aber zu Fehlern führt, sollte generell jedes case mit
einem break; abgeschlossen werden.
102
21 / 55
5.3 Die for-Schleife
22
Verwendung der for-Schleife
Die for-Schleife wird meist verwendet, um eine Folge von
Anweisungen (Block) mehrfach auszuführen. Die Zahl der
Ausführungen ist dabei oft vorher klar (feste Zahl oder begrenzt
durch Wert einer Variablen). Daher werden for-Schleifen auch
Zählschleifen genannt. Dabei werden immer folgende Schritte
for (< Initialbefehl >; < Schleifenbedingung >; < Iteration > )
< Schleifenanweisung >;
< Initialbefehl >: Einmalig durchgeführte Anweisung.
Meist Deklaration+Initialisierung der Iterationsvariablen
(Schleifenindex).
ausgeführt:
1. Initiatbefehl wird einmal ausgeführt.
2. Bedingung wird geprüft:
< Schleifenbedingung >: Bedingung, die für die nächste
Ausführung der < Schleifenanweisung > erfüllt sein muss.
◮
◮
< Iteration >: Hochzählen des Schleifenindex.
Falls true: Anweisungen werden ausgeführt.
Falls false: Schleife wird beendet.
3. Iteration wird ausgeführt.
< Schleifenanweisung >: Einzelne Anweisung oder Block von
Anweisungen.
4. Weiter bei 2.
Häufigste Art der Verwendung:
for( int i=0; i<xyz; i++)
{tuwas;}
23 / 55
24
Beispiel für for-Schleife (ForIter.java)
1.
2.
3.
4.
5.
6.
Beispiel für for-Schleife (ForIter.java)
1.
2.
3.
4.
5.
6.
public static void main(String[] args)
{
int anzahl=3;
for ( int i=0; i<anzahl; i++)
System.out.println(i);
}
public static void main(String[] args)
{
int anzahl=3;
for ( int i=0; i<anzahl; i++)
System.out.println(i);
}
Der Anfangsbefehl wird genau einmal ausgeführt.
i
erhält einmalig den Wert 0.
0
1
2
0
1
2
25 / 55
Beispiel für for-Schleife (ForIter.java)
26
Beispiel für for-Schleife (ForIter.java)
1.
2.
3.
4.
5.
6.
1.
2.
3.
4.
5.
6.
public static void main(String[] args)
{
int anzahl=3;
for ( int i=0; i<anzahl; i++)
System.out.println(i);
}
Die Bedingung i<anzahl wird geprüft. Für i=0 und anzahl=3 wird der
0
Wert true zurückgegeben.
1
2
public static void main(String[] args)
{
int anzahl=3;
for ( int i=0; i<anzahl; i++)
System.out.println(i);
}
Also wird der Anweisungsblock wird ausgeführt.
0
Es
wird 0 auf dem Bildschirm ausgegeben.
1
2
27 / 55
28
Beispiel für for-Schleife (ForIter.java)
Beispiel für for-Schleife (ForIter.java)
1.
2.
3.
4.
5.
6.
1.
2.
3.
4.
5.
6.
public static void main(String[] args)
{
int anzahl=3;
for ( int i=0; i<anzahl; i++)
System.out.println(i);
}
Der Iterationsbefehl i++ wird ausgeführt.
i
hat nun den Wert 1.
0
1
2
public static void main(String[] args)
{
int anzahl=3;
for ( int i=0; i<anzahl; i++)
System.out.println(i);
}
Die Bedingung i<anzahl wird geprüft. Für i=1 und i=2 wird wieder
0
der Wert true zurückgegeben.
1
2
29 / 55
Beispiel für for-Schleife (ForIter.java)
30
Beispiel für for-Schleife (ForIter.java)
1.
2.
3.
4.
5.
6.
1.
2.
3.
4.
5.
6.
public static void main(String[] args)
{
int anzahl=3;
for ( int i=0; i<anzahl; i++)
System.out.println(i);
}
Der Anweisungsblock wird ausgeführt.
Es wird 1 und 2 auf dem Bildschirm aus0
gegeben
1
2
public static void main(String[] args)
{
int anzahl=3;
for ( int i=0; i<anzahl; i++)
System.out.println(i);
}
Der Iterationsbefehl i++ wird ausgeführt.
i hat nun den Wert 3.
0
1
2
31 / 55
32
Beispiel für for-Schleife (ForIter.java)
Fehlerquellen:
Die Schleifenanweisung kann (wie bei if) auch (versehentlich)
die leere Anweisung sein:
for( int i=0; i<xyz; i++); {tuwas;}
Hier wird tuwas; nur einmal, nach der Schleife ausgeführt.
1.
2.
3.
4.
5.
6.
public static void main(String[] args)
{
int anzahl=3;
for ( int i=0; i<anzahl; i++)
System.out.println(i);
}
Die Bedingung i<anzahl wird geprüft. Für i=3 und anzahl=3 wird der
0
Wert false zurückgegeben.
1
Die
Schleife wird beendet.
2
Ist die Fortsetzungsbedingung am Anfang falsch, so wird die
Schleifenanweisung nie ausgeführt:
int xyz=0;
for( int i=0; i<xyz; i++) {tuwas;}
Hier wird tuwas; wegen i<xyz = false nie ausgeführt.
Die Anzahl der Schleifendurchläufe wird oft falsch bestimmt,
insbesondere durch folgende Unterschiede:
i<xyz;
i<=xyz;
int i=0;
int i=1;
33 / 55
Sonderfälle
34
Allgemeine Fälle
for-Schleifen können natürlich geschachtelt werden:
for(int i=1; i<n; i++)
{
for(int j=1; j<m; j++)
{
System.out.println(i*j);
}
}
Bisher wurde Schleifenindex im Anfangsbefehl deklariert und
war nur in der Schleife bekannt. Deklaration ist auch vor der
Schleife möglich. Man kann dann auch nach Ende der Schleife
darauf zugreifen:
int i;
for(i=0; i<n; i++) {tuwas;}
System.out.println(i);
Die Iteration wird einmal nach jeder Schleifenanweisung
ausgeführt. Nach Ende der Schleife hat der Index den Wert,
für den die Fortsetzungsbedingung erstmals falsch war. Obiges
Programmfragment liefert also die folgende Ausgabe:
Bei einzelnen Anweisungen oder einem Anweisungsblock in nur
der innersten Schleife, kann die Schreibweise verkürzt werden:
for(int i=1; i<n; i++)
for(int j=1; j<m; j++)
System.out.println(i*j);
10
Bei geschachtelten Schleifen auf unterschiedliche
Schleifenindizes achten!
Achtung: Für Bedingung i<=10, ergibt sich die Ausgabe 11!
35 / 55
36
Beispiel 2 für for-Schleife (ForFakul.java)
Beispiel 2 für for-Schleife (ForFakul.java)
1. public static void main(String[] args)
2. {
3.
int f=1;
4.
for (int i=5; i>0; i--)
5.
f*=i;
6.
System.out.println(f);
7. }
1. public static void main(String[] args)
2. {
3.
int f=1;
4.
for (int i=5; i>0; i--)
5.
f*=i;
6.
System.out.println(f);
7. }
Die Variable i kann auch dekrementiert, statt in120 krementiert werden!
120
37 / 55
Beispiel 2 für for-Schleife (ForFakul.java)
38
Unbestimmte Schleifen
1. public static void main(String[] args)
2. {
3.
int f=1;
4.
for (int i=5; i>0; i--)
5.
f*=i;
6.
System.out.println(f);
7. }
Dann muss die Variable i nach unten begrenzt
120 werden!
Einzelne Elemente der for-Klammer können leer bleiben.
Es funktioniert auch:
for( ; ; ) {tuwas;}
Dabei ist eine leere Bedingung immer wahr, d.h. hier wird
tuwas; unendlich oft ausgeführt.
Trotz leerer Bedingung können die Schleifendurchläufe gezählt
werden:
for(int i=1; ; i++ ) {tuwas;}
39 / 55
40
Verlassen unbestimmter Schleifen
break und continue
Unbestimmte Schleifen können auf 2 Arten verlassen werden:
1. Es tritt eine “Ausnahme” (Exception) auf (später).
Mit break wird eine Schleife komplett abgebrochen, falls die
vorhergehende Bedingung erfüllt ist.
2. Die Schleife wird abhängig von einer Bedingung mit break
verlassen:
for(int i=1; ; i++ ) {
if (i>10) break;
}
Eventuell soll nur ein bestimmter Fall übersprungen werden,
für den die Schleife nicht durchgeführt werden soll.
Einmaliges überspringen des restlichen Schleifenkörpers
gelingt mit:
if (i==10) continue;
Ist die Bedingung erfüllt springt das Programm direkt zum
Ende des Durchlaufs und startet die Schleife mit dem
nächsten Durchlauf.
Beide Arten eine unbestimmte Schleife zu verlassen sind sehr
unschön, da sie zu unübersichtlichen, schwer zu verifizierenden
Programmen führen.
Daher sollten unbestimmte Schleifen immer vermieden werden.
Dies ist (manchmal aufwendiger, aber) immer möglich!
Eine Programmiersprache ist mit break nicht mächtiger als ohne!
41 / 55
Beispiel für continue
42
5.4 Die while-Schleife
for(int i=1; i<20 ; i++ )
{
if (i==10) continue;
System.out.println(i);
}
while (< Schleifenbedingung >)
< Schleifenanweisung >;
< Schleifenbedingung >: Bedingung, die für die nächste
Ausführung der < Schleifenanweisung > erfüllt sein muss.
Dieses Programmfragment gibt alle Werte von 1 bis 19 aus, ausser
der 10. Das gleiche ist aber leicht ohne continue möglich:
< Schleifenanweisung >: Einzelne Anweisung oder Block von
Anweisungen, die ausgeführt werden, falls
< Schleifenbedingung > true liefert.
for(int i=1; i<20 ; i++ )
{
if (i!=10) System.out.println(i);
}
43 / 55
44
Verwendung der while-Schleife
Beispiel für while-Schleife (WhileDo.java)
1. public static void main(String[] args)
2. {
3.
int zahl=64, i=0;
4.
while (zahl>1)
5.
{
6.
zahl/=2;
7.
if (zahl>0) i++;
8.
}
9.
System.out.println(i);
10. }
Im Gegesatz zur for-Schleife steht bei der while-Schleife die
Schleifenbedingung, nicht die Anzahl der Schleifendurchläufe eher
im Vordergrund. Um die Anzahl zu ermitteln, muss man selbst
einen Zählindex verwalten. Die Schleifenbedingung ist ein eher
komplexerer boolescher Ausdruck. Es werden immer folgende
Schritte ausgeführt:
1. Bedingung wird geprüft:
◮
◮
Falls true: Anweisungen werden ausgeführt.
Falls false: Schleife wird beendet.
2. Weiter bei 1.
6
45 / 55
Beispiel für while-Schleife (WhileDo.java)
46
Beispiel für while-Schleife (WhileDo.java)
1. public static void main(String[] args)
2. {
3.
int zahl=64, i=0;
4.
while (zahl>1)
5.
{
6.
zahl/=2;
7.
if (zahl>0) i++;
8.
}
9.
System.out.println(i);
10. }
Die Bedingung zahl>1 wird geprüft.
Für
zahl=64 wird der Wert true zurückge6
geben.
1. public static void main(String[] args)
2. {
3.
int zahl=64, i=0;
4.
while (zahl>1)
5.
{
6.
zahl/=2;
7.
if (zahl>0) i++;
8.
}
9.
System.out.println(i);
10. }
Der Anweisungsblock wird ausgeführt.
zahl wird ihre ganzzahlige Hälfte zugewie6
sen; da diese > 0 ist, wird i inkremeniert.
47 / 55
48
Beispiel für while-Schleife (WhileDo.java)
Beispiel für while-Schleife (WhileDo.java)
1. public static void main(String[] args)
2. {
3.
int zahl=64, i=0;
4.
while (zahl>1)
5.
{
6.
zahl/=2;
7.
if (zahl>0) i++;
8.
}
9.
System.out.println(i);
10. }
Die Bedingung wird erneut
(nun mit zahl=32) geprüft, usw...
6
1. public static void main(String[] args)
2. {
3.
int zahl=64, i=0;
4.
while (zahl>1)
5.
{
6.
zahl/=2;
7.
if (zahl>0) i++;
8.
}
9.
System.out.println(i);
10. }
Es wird der Exponent der grössten enthaltenen Zweierpotenz ausgegeben.
6
49 / 55
Sonderfälle
for vs. while
Eine leere Bedingung, ist bei while-Schleifen anders als bei
for-Schleifen standardmässig nicht vorgesehen (erzeugt
Kompilierfehler).
Eine Endlosschleife mittels while wird mit true als
Bedingung erreicht:
while (true) < Schleifenanweisung >;
Es gelten die gleichen Möglichkeiten zum verlassen einer
solchen Endlosschleife mit while wie mit for:
◮
◮
50
Die while-Schleife und for-Schleife sind äquivalent, es gilt:
for(Start; Bedingung; Änderung)
Anweisung;
entspricht:
Start;
while (Bedingung)
{
Anweisung;
Änderung;
}
Exceptions
break;
Auch hier kann continue; zum Überspringen einer
Ausführung verwendet werden.
while-Schleifen können verschachelt werden (Blöcke bilden!).
51 / 55
52
Bemerkung
5.5 Die do-Schleife
do < Schleifenanweisung >
while (< Schleifenbedingung >);
Wie in den Beispielen gesehen, werden die Bedingungen bei
for-Schleife und while-Schleife vor dem Durchlauf geprüft.
< Schleifenanweisung >: Einzelne Anweisung oder Block von
Anweisungen, die ausgeführt werden.
Manchmal ist es wünschenswert, mindestens einen Durchlauf
zu erlauben, bevor die Bedingung zum ersten Mal überprüft
wird.
< Schleifenbedingung >: Bedingung, die für die nächste
Ausführung der < Schleifenanweisung > erfüllt sein muss.
Daher : do-Schleife.
In do-Schleife entspricht der while-Schleife die allen Eigenschaften
ausser dem Zeitpunkt der Bedingungsüberprüfung.
53 / 55
Beispiel für do-Schleife (DoWhile.java)
1. public static void main(String[] args)
2. {
3.
int zahl=64, i=0;
4.
do
5.
{
6.
if (zahl>0) zahl/=2;
7.
i++;
8.
}
9.
while (zahl>1)
10.
System.out.println(i);
11. }
6
55 / 55
54
Herunterladen