1 Wiederholungsanweisungen while-Anweisung - while - ( - logischer Ausdruck - ) - Anweisung Wirkung: Solange der logische Ausdruck den Wert true liefert, wird die Anweisung ausgeführt. Als Struktogramm geschrieben (kopfgesteuerte Schleife): logischer Ausdruck Anweisung Gäbe es die unbedingte Sprunganweisung goto in Java und wäre marke das Sprungziel, so könnte man sich die Wirkung while-Anweisung (in einfachen Fällen) folgendermaßen veranschaulichen: marke: if (logischer Ausdruck) { Anweisung goto marke; } Beispiel: Mittelwertberechnung von n Zahlen import java.util.*; public class Mittelwert { public static void main(String args[]) { Scanner scanner = new Scanner(System.in); int k=0; double x,s=0; System.out.println("Werte eingeben (Abbruch mit Ctrl-D unter Linux): "); while(scanner.hasNextDouble()) { x = scanner.nextDouble(); k = k+1; s = s+x; } if (k>0) System.out.println("Zahl der Messwerte: "+k+" Mittelwert: "+s/k); else System.out.println("Zahl der Messwerte: "+k); } } do-while-Anweisung - do - Anweisung - while - ( - logischer Ausdruck - ) - ; Wirkung: Die Anweisung wird mindestens einmal ausgeführt und solange wiederholt, wie der logische Ausdruck den Wert true liefert. Als Struktogramm geschrieben (fußgesteuerte Schleife): Informationsblatt 6 - SS 2010 2 Anweisungen logischer Ausdruck Die Wirkung der do-while Anweisung kann man sich (in einfachen Fällen) so vorstellen: Anweisung while (logischer Ausdruck) Anweisung Beispiel: Größter gemeinsamer Teiler natürlicher Zahlen a,b import java.util.*; public class ggT{ public static void main(String args[]) { Scanner scanner = new Scanner(System.in); int a,b,r; System.out.print("a b: "); a = scanner.nextInt(); b = scanner.nextInt(); do { r = a%b; a = b; b = r; } while (r!=0); System.out.println("ggT: "+a); } } Beispiel: Heronverfahren zur näherungsweisen Berechnung der Quadratwurzel √ Zu a > 0 und x0 > 0 betrachte xi+1 := 21 (xi + xai ) (i = 0, 1, . . .). Dann gilt: lim xi = a n→∞ Abbruch der Iteration, falls |xi −xi+1 | ≤ ε (Genauigkeit erreicht) oder wenn eine Iterationsschranke itmax überschritten ist. Schrittweise Verfeinerung: 0. Problem 1. Eingabe von a, x0 , ε und itmax 2. Durchführung der Iteration 3. Ausgabe der Ergebnisse 1. Verfeinerungsschritt 1.1 Einlesen von a, x0 , ε, itmax und Kontrollausgabe 2.1 Prüfen ob a > 0 und x0 > 0, andernfalls entsprechende Meldung und Abbruch. 2.2 Iterationsschleife. 3.1 Ausgabe der gefundenen Näherung und der Zahl der Iterationsschritte. 3.2 Ausdrucken, welches Abbruchkriterium erfüllt wurde. Informationsblatt 6 - SS 2010 3 Java-Programm: import java.util.*; public class Heronverfahren { public static void main(String args[]) { Scanner scanner = new Scanner(System.in); double a,eps,x0,x1; int i,itmax; // 1.1 Eingabe mit Kontrollausgabe System.out.print("a x0 eps itmax: "); a = scanner.nextDouble(); x0 = scanner.nextDouble(); eps = scanner.nextDouble(); itmax = scanner.nextInt(); // P1 // 1.2 Ueberpruefung, ob a und x0 sinnvoll if (a<=0 || x0<=0) { System.out.println("Radikand oder Startwert nicht positiv"); System.exit(0); } // 2.1 Iterationsschleife x1 = 0.5*(x0+a/x0); i=1; // P2 while (Math.abs(x1-x0)>eps && i<itmax) { x0 = x1; x1 = 0.5*(x0+a/x0); i = i+1; // P3 } // 3.1 Ausgabe der Naeherung und der Zahl der Iterationsschritte System.out.println("Naeherung = "+x1+" nach "+i+" Iterationsschritten"); // P4 // 3.2 Ausgabe des Abbruchkriteriums if (Math.abs(x1-x0)<=eps) System.out.println("Genauigkeit erreicht"); if (i>=itmax) System.out.println("Iterationsschranke erreicht"); } } Trace (Angabe der zeitlichen Veränderung aller Variablen) a = 9, x0 = 5, ε = 0.5, itmax = 3 Stelle P1 P2 x0 5 P3 P4 3.4 x1 i |x1 − x0 | 3.4 1 1.6 x1 := 12 (5 + 95 ) 3.0235 3.0235 2 2 0.3765 x1 := 12 (3.4 + a 9 ε 0.5 itmax 3 Kommentar 9 3.4 ) for-Anweisung Die for-Anweisung in Java dient vor allem als Laufanweisung, ist aber allgemeiner definiert. - for - ( - Init.ausdr. ? - ; - log. Ausdr. ? - ; - Update-Ausdr. ? - ) - Anweisung Informationsblatt 6 - SS 2010 4 Diese Anweisung ist äquivalent zu Init.ausdr. ; while (log. Ausdr.) { Anweisung Update-Ausdr. ; } Die Ausdrücke in der for-Anweisung können ganz oder teilweise fehlen; fehlt der mittlere Ausdruck so gilt er als wahr. Beispiele: – n! = n Q i = 1 · 2···n i=1 fak=1; for (i=1; i<=n; ++i) fak = fak*i; Der linksassoziative Kommaoperator faßt zwei Ausdrücke syntaktisch zu einem einzigen Ausdruck zusammen. Datentyp und Wert des Ausdrucks sind die des rechten Operanden. Die durch Kommas getrennten Funktionsargumente oder Deklarationen sind keine Kommaausdrücke. Man hätte als auch schreiben können: for (i=1,fak=1; i<=n; ++i) fak = fak*i; – Binomialkoeffizient n k ! = n(n − 1) · · · (n − k + 1) 1···k (k, n ∈ IN) int b,i,k,n; for (i=1,b=1; i<=k; --n,++i) b=b*n/i; – for(;;) { ... } entspricht while(true) { ... } (“forever“) break-Anweisung - break - ; Wirkung: break beendet die kleinste umschließende Wiederholungsanweisung (oder Auswahlanweisung). Beispiel: Andere Formulierung der Iterationsschleife des Heronverfahrens for (i=1; i<=itmax; ++i) { x1 = 0.5*(x0+a/x0); if (Math.abs(x1-x0) <= eps) break; x0 = x1; } Bemerkung: Der Java-Compiler geht davon aus, dass alle Variablen, auf deren Wert zugegriffen wird, immer initialisiert sind. Wird z.B. eine Wiederholungsausweisung unter bestimmten Bedingungen nicht ausgeführt und hat eine Variable dadurch keinen Wert, so wird ein Fehler gemeldet und das Programm nicht übersetzt. In diesem Beispiel ist die Verwendung von x1 nach der for-Schleife somit nur möglich, wenn x1 zuvor im Programm mit einem Wert versehen wurde. Die allgemeinere break-Anweisung mit Marke wird hier nicht behandelt.