252-0027
Einführung in die Programmierung
2.0 Einfache Java Programme
Thomas R. Gross
Department Informatik
ETH Zürich
Übersicht
§ 2.6 Nochmals Schleifen
§ “while” Loops
§ 2.7 Methoden mit Rückgabewerten
§ 2.8 Sichtbarkeit von Deklarationen
§ 2.9 Nützliche Klassen (Input, Math, Random)
§ 2.X Input
182
Übersicht
§ 2.7 Methoden mit Rückgabewerten
§ 2.8 Sichtbarkeit von Deklarationen
§ 2.9 Nützliche Klassen (Input, Math, Random)
§ 2.X Input
183
2.6 Nochmals Schleifen
§ Kurzform zur Aktualisierung des Loop Counters (Schleifenzählers)
§ Flexible Obergrenze für Schleifenzähler
§ Bisher: stand zu Beginn der Schleife fest
§ Jetzt: Berechnung zur Laufzeit
§ Tipps für korrekte Terminierung der Schleifen
184
Aktualisierung
for (int i = start ; i < bound; i = i + 1) {
// Statement
}
Aktualisierung: i wird um 1 erhöht
for (int i = start ; i > bound; i = i - 1) {
// Statement
}
Aktualisierung: i wird um 1 reduziert
Auch andere Aktualisierungen sind möglich aber diese hier
treten häufig auf
185Kurzformen für Zuweisungen
§ Zuweisungen der Form j = j+1 tretten häufig auf
§ Machen Programm unübersichtlich
§ Früher: unnötige Extra-Arbeit für Compiler und Computer
§ Kurzformen erlauben Inkrement (Addition von 1) und Dekrement (Subtraktion von 1)
§ “increment” und “decrement” Operator
§ Veränderung immer um 1
186
Inkrement und Dekrement
Kurzform Äquivalente ausführlichere Version
variable++; variable = variable + 1; //increment
variable--; variable = variable - 1; //decrement
Beispiele
int x = 2;
x++; // x = x + 1;
// x now stores 3 double note = 4.5;
note--; // note = note - 1;
// note now stores 3.5
187Aktualisierung
for (int i = start ; i < bound; i++) {
// Statement
}
Aktualisierung: i wird um 1 erhöht
for (int i = start ; i > bound; i--) {
// Statement
}
Aktualisierung: i wird um 1 reduziert
++ (und --) oft in Aktualisierungen des Loop Counters
188
Inkrement und Dekrement
Kurzform Äquivalente ausführlichere Version
variable++; variable = variable + 1;
variable--; variable = variable - 1;
Variable wird verwendet und dann verändert
Dies gilt auch in Ausdrücken und Zuweisungen
Beispiel
int x = 2;
int y;
y = x++;
189
Inkrement und Dekrement
Kurzform Äquivalente ausführlichere Version
variable++; variable = variable + 1;
variable--; variable = variable - 1;
Variable wird verwendet und dann verändert
Dies gilt auch in Ausdrücken und Zuweisungen
Beispiel
int x = 2;
int y;
y = x++;
190
int temp = x;
x++;
y = temp;
//x:
//y:
Inkrement und Dekrement
Kurzform Äquivalente ausführlichere Version
variable++; variable = variable + 1;
variable--; variable = variable - 1;
Variable wird verwendet und dann verändert
Dies gilt auch in Ausdrücken und Zuweisungen
Beispiel
int x = 2;
int y;
y = x++;
191
int temp = x;
x = x + 1;
y = temp;
//x:
//y:
192
194
Inkrement und Dekrement Puzzles
int x = 1;
int y = 0;
int z = 0;
y = x++;
z = x++ + x++;
§ Wert x?
§ Wert y?
§ Wert z?
int a = 1;
a = a++;
§ Wert a?
int i = 10;
int j = i-- - i--;
§ Wert i?
§ Wert j?
1950 1 2 3 4 5 6
Inkrement und Dekrement Puzzles
int i = 10;
int j = i-- - i--;
// in Zeitlupe int i = 10;
int temp1 = i; // 10 i = i - 1; // 9 int temp2 = i; // 9 i = i – 1; // 8 j = temp1 – temp2; // 1
§ Wert i? 8
§ Wert j? 1
196int a = 1;
a = a++;
// in Zeitlupe int a = 1;
int temp = a; // 1 a = a + 1; // 2 a = temp; // 1
§ Wert a? 1
Inkrement und Dekrement Puzzles
198
§ Unser Ziel ist es verständliche Programme zu schreiben
Inkrement und Dekrement Puzzles
199
§ Unser Ziel ist es verständliche Programme zu schreiben
§ … und nicht Puzzles zu konstruieren!
§ Sie sollten ++ und -- (er)kennen
§ Auch in komplexen Ausdrücken
§ Ihre Entscheidung ob sie es verwenden (aber wenn dann richtig)
§ Diese Operatoren sind nicht so effizient dass wir dafür die
Klarheit eines Programmes opfern wollen.
Weitere Kurzformen
§ Erlauben Verwendung des Wertes einer Variable gefolgt von einer Modifikation (Zuweisung)
Kurzform Äquivalente ausführlichere Version variable += value; variable = variable + value;
variable -= value ; variable = variable - value ; variable *= value; variable = variable * value;
variable /= value; variable = variable / value;
variable %= value; variable = variable % value;
§ Modifikation mit beliebigen Werten (nicht nur 1)
200
Weitere Kurzformen
Beispiele
x += 3; // x = x + 3;
note -= 0.5; // note = note - 0.5;
number *= 2; // number = number * 2;
Warnung :
x += 1; // x = x + 1;
x =+ 1; // x = + 1;
201
Bedingte ("short-circuit") Auswertung
§ Für && und || müssen nicht immer beide Operanden
ausgewertet werden, um das Ergebnis zu ermitteln
§ Java beendet die Auswertung eines booleschen Ausdrucks sobald das Ergebnis fest steht.
§ && und || sind links-assoziativ
§ Ausdrücke werden von links nach rechts, gemäss Präzedenz und Assoziativität ausgewertet
§ && stoppt sobald ein Teil(ausdruck) false ist
§ || stoppt sobald ein Teil(ausdruck) true ist
Bedingte Auswertung: Vorsicht
§ Was ist der Wert von count am Ende des Codesegments?
// look closely int count = 0;
Scanner console = new Scanner(System.in);
for (int i; i<4; i++) {
System.out.print("Eingabe Zahl: ");
int wert = console.nextInt();
if ((wert != 0) && (count++ < 9)) { System.out.println("Hit");
}
} // count: Anzahl Werte ungleich 0, nicht Iterationen
§ Vorsicht bei ++/--
Bedingte Auswertung: Vorsicht
§ Die logischen Operatoren sind nicht kommutativ wenn die Auswertung den Zustand des Programms verändern kann.
§ (expr1 && expr2) nicht immer gleich (expr2 && expr1)
§ Vorsicht bei Operatoren mit Nebenwirkungen (“side effects”)
§ Offensichtliche Nebenwirkungen: z.B. int x,y; x++ y-- o. ä.
§ Nicht sofort offensichtlich:
§ int x, y; x/y x%y
Kurzformen zur Kontrolle einer Schleife
§ Kurzform häufig in Aktualisierungsblock einer Schleife for (int i = 1; i <= 6; i++) {
System.out.println("Ich werde die Uebungsaufgaben machen");
}
§ Nachdem alle Anweisungen im Schleifenrumpf (“body”) ausgeführt wurden findet die Aktualisierung (der
Zählervariable) statt
205
Eine triviale Aufgabe ...
§ Schreiben Sie eine Methode printNumbers die die Zahlen von 1 bis N durch Komma getrennt ausgibt.
Beispiel:
Obergrenze N eingeben: 5
sollte ergeben:
1, 2, 3, 4, 5
Lösungsansatz
public static void printNumbers() {
Scanner console = new Scanner(System.in);
System.out.print("Obergrenze N eingeben: ");
int max = console.nextInt();
for (int i = 1; i <= max; i++) { System.out.print(i + ", ");
}
System.out.println(); // to end the line of output
}
Fehlerhafte Lösungen
public static void printNumbers() {
Scanner console = new Scanner(System.in);
System.out.print("Obergrenze N eingeben: ");
int max = console.nextInt();
for (int i = 1; i <= max; i++) { System.out.print(i + ", ");
}
System.out.println(); // to end the line of output }
Output bei Eingabe 5: 1, 2, 3, 4, 5,
Fehlerhafte Lösungen
public static void printNumbers() {
Scanner console = new Scanner(System.in);
System.out.print("Obergrenze N eingeben: ");
int max = console.nextInt();
for (int i = 1; i <= max; i++) { System.out.print(", " + i);
}
System.out.println(); // to end the line of output }
Output bei Eingabe 5: , 1, 2, 3, 4, 5
Gartenzaun Analogie
§ Wir geben n Zahlen aus aber brauchen nur n - 1 Kommas.
§ Ähnlich dem Bau eines Weidezaunes mit Pfosten und Querstreben
§ Wenn wir – wie in der 1. fehlerhaften Lösung – Pfosten und Streben installieren dann hat der letzte Pfosten in der Luft hängende Streben.
for (Länge des Zauns) { Betoniere Pfosten.
Installiere Querstreben.
}
Gartenzaun Analogie
§ Wir geben n Zahlen aus aber brauchen nur n - 1 Kommas.
§ Ähnlich dem Bau eines Weidezaunes mit Pfosten und Querstreben
§ Wenn wir – wie in der 2. fehlerhaften Lösung – Streben und Pfosten installieren dann hat der erste Pfosten in der Luft hängende Streben.
for (Länge des Zauns) { Installiere Querstreben.
Betoniere Pfosten.
}
Schleife
§ Fügen Sie eine Anweisung ausserhalb der Schleife hinzu um den ersten "Pfosten" zu plazieren
Betoniere Pfosten.
for (Länge des Zauns - 1) { Installiere Querstreben.
Betoniere Pfosten.
}
Lösungen basierend auf dieser Idee
System.out.print(1);
for (int i = 2; i <= max; i++) { System.out.print(", " + i);
}
System.out.println(); // to end the line
Alternative: 1. oder letzter Durchlauf durch die Schleife kann verändert werden:
for (int i = 1; i <= max - 1; i++) { System.out.print(i + ", ");
}
System.out.println(max); // to end the line
Lösung (eine Möglichkeit)
public static void printNumbers() {
Scanner console = new Scanner(System.in);
System.out.print("Obergrenze N eingeben: ");
int max = console.nextInt();
System.out.print(1);
for (int i = 2; i <= max; i++) { System.out.print(", " + i);
}
System.out.println(); // to end the line
}
"off-by-one" Error (Um-Eins-daneben-Fehler)
§ Die Schleife wurde einmal zuviel (oder einmal zuwenig) durchlaufen.
§ "Zaunpfahlproblem" – es gibt sogar eine D Wikipedia Seite (Inhalt ohne Gewähr)
216
Terminierung von Loops
§ Verwandeln Sie die Methode printNumbers in eine neue Methode printPrimes die alle Primzahlen (durch Komma getrennt) bis zur Obergrenze max ausgibt.
§ Beispiel: printPrimes mit Eingabe 50 ergibt:
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47
§ Wenn max < 2, gebe nichts aus.
§ Eine Primzahl p kann in genau zwei Faktoren zerlegt werden:
p und 1
import java.util.*;
class PrintPrimes1 {
public static void main (String[] args) { Scanner console = new Scanner(System.in);
System.out.print("Input max: ");
int max = console.nextInt();
if (max >= 2) {
printPrimes(max);
} }
public static void printPrimes(int limit)
// Prints all prime numbers up to limit, limit >= 2 System.out.print("2");
for (int candidate = 3; candidate <= limit; candidate++) { if ( /* isPrime(candidate) */ ) {
System.out.print(", " + candidate);
} }
System.out.println(); // to end output
}
}public static void printPrimes(int limit) {
// Prints all prime numbers from 2 up to the given limit // limit >= 2
System.out.print("2");
for (int candidate = 3; candidate <= limit; candidate++) { // Determine if candidate is prime
// Count factors! 2: prime, >2 not prime int count = 0;
for (int j = 1; j<=candidate; j++) { if (candidate % j == 0) {
count++;
} }
if (count == 2) {
System.out.print(", " + candidate);
} }
System.out.println(); // to end output
}
while Schleifen
Klassifizierung von Schleifen
§ bestimmte Schleife (definite loop): Anzahl der Ausführungen des Rumpfes ist vorher bekannt.
§ Die for Schleifen waren bisher immer bestimmte Schleifen.
§ Drucke "hello" 10-mal.
§ Finden Sie alle Primzahlen < einer ganzen Zahl n.
§ Drucken Sie jede ungerade Zahl zwischen 7 und 91.
§ unbestimmte Schleife (indefinite loop): Anzahl der
Ausführungen des Rumpfes ist nicht vorher bekannt.
Beispiele von unbestimmten Schleifen
§ unbestimmte Schleife (indefinite loop): Anzahl der Ausführungen des Rumpfes ist nicht vorher bekannt.
§ Lesen Sie den Input von der Konsole bis der Benutzer eine nicht- negative ganze Zahl eingibt.
§ Wiederholen Sie bis der Benutzer ein "q" eingegeben hat.
§ Lesen Sie eine Datei bis drei aufeinanderfolgende Sätze mit einem "!" enden.
§ Nehmen Sie Beiträge (via crowdfunding) entgegen bis das Ziel
erreicht ist.
Die while Schleife
§ while Schleife: Führen Sie den Schleifenrumpf so lange aus wie der boolesche Ausdruck test den Wert true ergibt.
while ( test ) { statement(s);
}
§ Beispiel:
int num = 1; // initialization while (num*num <= 2000) { // test
System.out.print(num + " ");
num = num * 2; // update }
// output: 1 2 4 8 16 32
Die while Schleife
§ while Schleife: Führen Sie den Schleifenrumpf so lange aus wie der boolesche Ausdruck test den Wert true ergibt.
while ( test ) { statement(s);
}
§ Beispiel:
int num = 1;
while (num*num <= 2000) { System.out.print(num + " ");
num = num * 2;
}
// output: 1 2 4 8 16 32
Anweisung(en) im Loop ausführen Ist test wahr?
Anweisung nach Loop ausführen
ja nein
Beispiel while Schleife
// finds the first factor of 91, other than 1 int n = 91;
int factor = 2;
while (n % factor != 0) { factor++;
}
System.out.println("First factor is " + factor);
// output: First factor is 7
§ while ist hier bessser als for weil wir nicht wissen wie oft wir den
Zähler erhöhen müssen um den 1. Faktor zu finden
// Prints all prime numbers up to the given max.
public static void printPrimes(int limit) {
// Prints all prime numbers from 2 up to the given limit // limit >= 2
System.out.print("2");
for (int candidate = 3; candidate <= limit; candidate++) { // Determine if candidate is prime
// Find another factor <> 1: factor == candidate: candidate prime int count = 0;
int maybeFactor = 2;
while (count==0) {
if (candidate % maybeFactor == 0) { count++;
} else { // keep on searching maybeFactor++;
}
if (maybeFactor == candidate) { // prime!
System.out.print(", " + candidate);
} }
System.out.println(); // to end output }
§ Hinweiszeichen (Sentinel) ("sentinel"): Ein Wert der das Ende eine Reihe anzeigt
§ sentinel loop: Schleife deren Rumpf ausgeführt wird bis ein Sentinel gesehen wurde
§ Beispiel: Ein Programm soll Zahlen einlesen bis der Benutzer eine 0 eingibt; dann soll die Summe aller eingegebenen
Zahlen ausgegeben werden.
§ (In diesem Beispiel ist 0 das Hinweiszeichen/der Sentinel.)
Werte die Hinweise sind …
§ Beispiel: Ein Programm soll Zahlen einlesen bis der Benutzer eine 0 eingibt; dann soll die Summe aller eingegebenen
Zahlen ausgegeben werden.
§ (In diesem Beispiel ist 0 das Hinweiszeichen/der Sentinel.) Enter a number (0 to quit): 10
Enter a number (0 to quit): 20 Enter a number (0 to quit): 30 Enter a number (0 to quit): 0 The sum is 60
Werte die Hinweise sind …
Fehlerhafte Lösung
§ Was ist an diesem Programm schlecht?
Scanner console = new Scanner(System.in);
int sum = 0;
int number = 1; // "dummy value", anything but 0
while (number != 0) {
System.out.print("Enter a number (0 to quit): ");
number = console.nextInt();
sum = sum + number;
}
System.out.println("The total is " + sum);
Ein anderes Hinweiszeichen …
§ Ändern Sie das Programm so dass -1 der Sentinel ist.
§ Example log of execution:
Enter a number (-1 to quit): 15
Enter a number (-1 to quit): 25
Enter a number (-1 to quit): 10
Enter a number (-1 to quit): 30
Enter a number (-1 to quit): -1
The total is 80
Ein anderes Hinweiszeichen …
§ Setzen Sie den Sentinel auf -1:
Scanner console = new Scanner(System.in);
int sum = 0;
int number = 1; // "dummy value", anything but -1
while (number != -1) {
System.out.print("Enter a number (-1 to quit): ");
number = console.nextInt();
sum = sum + number;
}
System.out.println("The total is " + sum);
§ Jetzt ist das Result falsch. Warum?
The total was 79
Fehlerhafte Lösung – 0 à -1
§ Was ist an diesem Programm falsch?
Scanner console = new Scanner(System.in);
int sum = 0;
int number = 1; // "dummy value", anything but 0
while (number != 0) {
System.out.print("Enter a number (0 to quit): ");
number = console.nextInt();
sum = sum + number;
}
System.out.println("The total is " + sum);
Das Problem mit diesem Programm
§ Unser Programm folgt diesem Muster:
summe = 0.
while (input ist nicht der sentinel) { drucke prompt; lese input.
addiere input zu summe.
}
§ Beim letzten Durchlauf durch den Rumpf wird der Sentinel -1
zur Summe addiert:
Das Problem mit diesem Programm
§ Beim letzten Durchlauf durch den Rumpf wird der Sentinel -1 zur Summe addiert:
drucke prompt; lese input (-1).
addiere input (-1) zu summe.
§ Beispiel inkorrekter Terminierung (off-by-one error, Zaunpfahlproblem):
§ Müssen N Zahlen lesen aber nur die ersten N-1 addieren.
241
Beispiel mit Sentinel
Scanner console = new Scanner(System.in);
int sum = 0;
// pull one prompt/read ("post") out of the loop System.out.print("Enter a number (-1 to quit): ");
int number = console.nextInt();
while (number != -1) {
sum = sum + number; // moved to top of loop System.out.print("Enter a number (-1 to quit): ");
number = console.nextInt();
}
System.out.println("The total is " + sum);
do/while Schleife
§ do/while Schleife: Führt test am Ende des Schleifenrumpfes aus um zu entscheiden, ob ein weiterer Durchlauf nötig ist
§ Stellt sicher dass der Rumpf { … } mindestens einmal ausgeführt wird.
do {
statement(s) ; } while (test);
Anweisung(en) im Loop ausführen
Ist test wahr?
Anweisung nach Loop ausführen
ja
nein
do/while Schleife
§ Beispiel:
// Example: prompt until correct // PIN is typed
int input;
do {
System.out.print("Type your PIN: ");
input = console.nextInt();
} while (input != userPinCode);
Anweisung(en) im Loop ausführen
Ist test wahr?
Anweisung nach Loop ausführen
ja
nein
2.7 Ergebnis Rückgabe für Methoden
246
import java.util.*;
class PrintPrimes1 {
public static void main (String[] args) { Scanner console = new Scanner(System.in);
System.out.print("Input max: ");
int max = console.nextInt();
if (max >= 2) {
printPrimes(max);
} }
public static void printPrimes(int limit)
// Prints all prime numbers up to limit, limit >= 2 System.out.print("2");
for (int i = 3; i <= limit; i++) { if ( /* isPrime(i) */ ) {
System.out.print(", " + i);
} }
System.out.println(); // to end output }
}
2.7 Ergebnis Rückgabe
§ Parameter erlauben Kommunikation vom Aufrufer zur aufgerufenen Methode
§ Bisher waren die Methoden sehr einfach
§ Methode als "Ersatz" für Anweisungen in main (oder anderer Methode)
§ Methoden können aber mehr …
§ Ein Rückgabewert (“return value”) erlaubt der aufgerufenen Methode dem Aufrufer einen Wert zu übermitteln
§ Damit eröffnen sich neue Möglichkeiten der Komposition
248
250
{
…
name ( 7+i, true);
… }
public static name(int k,
boolean b) { int result;
while (k++ < 10) { … } if (b) { … }
// result
}
251
{
…
name ( 7+i, true);
… }
public static name(int k,
boolean b) { int result;
while (k++ < 10) { … } if (b) { … }
// result
}
252
{
…
name ( 7+i, true);
… }
public static name(int k,
boolean b) { int result;
while (k++ < 10) { … } if (b) { … }
// result
}
Rückgabe eines Wertes
§ Ein Rückgabewert muss deklariert werden
public static type name(parameters) { statements;
...
return expression;
}
§ Es gelten die selben Regeln für type wie bei der Deklaration
von Variablen und Parametern
Rückgabe Anweisung
§ Das return Statement (Rückgabe Anweisung) wertet einen Ausdruck aus .
§ Der Wert wird dann an den Aufrufer “zurückgegeben”
§ Der Ausdruck muss einen Wert des Typs type (der Methoden Deklaration) ergeben.
§ Die Ausführung der return Anweisung beendet die
aufgerufene Methode.
Rückgabeanweisung (“return”)
§ return : Liefere einen Wert ab als das Ergebnis dieser Methode
§ “sende” das Ergebnis zum Aufrufer
§ Das Gegenstück zu Parametern:
§ Parameters schicken Werte in die aufgerufene Methode, vom Aufrufer
§ Rückgabewerte schicken Werte aus der Methode zum Aufrufer
§ Ein Methodenaufruf kann Teil eines Ausdrucks sein.
§ Aufrufer muss den Wert "annehmen"
257
{
…
int size = name ( 7+i, true);
… }
public static int name(int k,
boolean b) { int result;
while (k++ < 10) { … } if (b) { … }
return result;
}
Rückgabeanweisung (“return”)
main
abs(-42) -42
round(2.71) 2.71
42
3
abs(-81) -81
81
Beispiellösung mit Rückgabe eines Wertes
public static boolean isPrime (int arg){
// Determine how many factors the given number has.
boolean found = false;
int step = 2;
while (!found) {
if (arg % step == 0) {
found = true; // another factor found } else { step++ ; // keep on searching } }
// other factor == arg: prime found return (step == arg);
}
Rückgabe eines Wertes
Beispiel:
// Returns the slope of the line between the given points.
public static double slope(int x1, int y1, int x2, int y2) { double dy = y2 - y1;
double dx = x2 - x1;
return dy / dx;
}
slope(1, 3, 5, 11) liefert 2.0
return ohne einen Wert
Wenn eine Methode keinen Wert zurück liefert dann braucht ein return Statement keinen Wert zu schicken.
public static void printPoint(int x, int y) {
System.out.println(“x = “ + x + “ y = “ + y)
;
return;
}
In dem Fall kann man das return Statement auch weglassen
(meine Empfehlung)
Weitere Beispiele
// Converts degrees Fahrenheit to Celsius.
public static double fToC(double degreesF) {
double degreesC = 5.0 / 9.0 * (degreesF - 32);
return degreesC;
}
// Computes triangle hypotenuse length given its side lengths.
public static double hypotenuse(int a, int b) { double c = squareRoot(a * a + b * b);
return c;
}
Weitere Beispiele
Ein return Statement kann auch einen (arithmetischen oder booleschen) Ausdruck verwenden
public static double fToC(double degreesF) { return 5.0 / 9.0 * (degreesF - 32);
}
Mögliche Fehler: Resultat nicht gespeichert
§ Ein return Statement schickt einen Wert an den Aufrufer
§ Namen, die in der aufgerufenen Methode verwendet
werden, sind belanglos (für den Aufrufer)
Was ist hier nicht richtig?
public static void main(String[] args) { slope(0, 0, 6, 3);
System.out.println("The slope is " + result); // ERROR:
} // result not defined
public static double slope(int x1, int x2, int y1, int y2) { double dy = y2 - y1;
double dx = x2 - x1;
double result = dy / dx;
return result;
}
Den Fehler vermeiden
§ return schickt den Wert der Variable zurück zum Aufrufer.
§ Der zurückgegebene Wert muss gespeichert werden – oder in einem Ausdruck verwendet werden.
§ Der Compiler generiert keine Warnung oder Fehlermeldung
wenn dies vergessen wird.
Den Fehler vermeiden
public static void main(String[] args) { double s = slope(0, 0, 6, 3);
System.out.println("The slope is " + s);
}
public static double slope(int x1, int x2, int y1, int y2) { double dy = y2 - y1;
double dx = x2 - x1;
double result = dy / dx;
return result;
}
return Anweisungen
§ Eine Methode kann mehrere return Anweisungen enthalten.
§ Sinnvoll für Fallunterscheidungen
§ Eine Methode die einen Rückgabewert deklariert muss eine (oder mehrere) return Anweisung(en) enthalten
269
if/else mit return
// Returns the larger of the two given integers.
public static int max(int a, int b) { if (a > b) {
return a;
} else {
return b;
} }
§ Methoden können ein return Statement in durch if/else kontrollierten Blöcken enthalten
§ Das return am Ende eines Pfades liefert den Rückgabewert für diese
Methode.
if/else mit return
§ Die Ausführung eines return Statements beendet die aufgerufene Methode.
§ Einem return sollten keine weiteren Anweisungen folgen
§ Alle Pfade durch eine Methode müssen ein return Statement enthalten
§ Wenn die Methode einen Rückgabewert deklariert hat
Alle Pfade …
public static int max(int a, int b) { if (a > b) {
return a;
}
// Error: not all paths return a value }
§ Der Compiler ist manchmal naiv:
public static int max(int a, int b) { if (a > b) {
return a;
} else if (b >= a) { return b;
} }
Der Compiler meint dass es einen Pfad ohne return gibt.
273
274
if/else , return Beispiel
§ Schreiben Sie eine Methode quadrant die für ein Paar von reellen Zahlen den Quadranten liefert in dem dieser Punkt liegt.
§ Bespiel: quadrant(-4.2, 17.3) liefert 2
§ Fällt der Punkt auf eine der Achsen des Koordinatensystems liefere 0 .
x+
x-
y+
y-
quadrant 1 quadrant 2
quadrant 3 quadrant 4
277
if/else , return Beispiellösung
public static int quadrant(double x, double y) { if (x > 0 && y > 0) {
return 1;
} else if (x < 0 && y > 0) { return 2;
} else if (x < 0 && y < 0) { return 3;
} else if (x > 0 && y < 0) { return 4;
} else { // at least one coordinate equals 0 return 0;
} }
if/else , return weitere Beispiele
§ Schreiben Sie eine Methode countFactors die die Anzahl der Faktoren (Teiler) einer Zahl liefert.
§ countFactors(24) liefert 8 da
1, 2, 3, 4, 6, 8, 12, und 24 alle Teiler von 24 sind.
if/else , return weitere Beispiele
§ Lösung:
// Returns how many factors the given number has.
public static int countFactors(int number) { int count = 0;
for (int i = 1; i <= number; i++) { if (number % i == 0) {
count++; // i is a factor of number }
}
return count;
}
2.8 Sichtbarkeit von Variablennamen
§ "Scope"
§ 1. Approximation
§ Weitere Aspekte in späteren Vorlesungen
281
Scope (Sichtbarkeitsbereich)
scope: Der Teil eines Programm in dem eine Variable sichtbar ist.
§ Variable müssen deklariert sein bevor sie sichtbar sind
§ Deklarationen müssen eindeutig sein
§ Sichtbar von Deklaration bis zum Ende des Blocks für den die Variable
deklariert ist
Scope (Sichtbarkeitsbereich)
scope: Der Teil eines Programm in dem eine Variable sichtbar ist.
§ Variable müssen deklariert sein bevor sie sichtbar sind
§ Deklarationen müssen eindeutig sein
§ Sichtbar von Deklaration bis zum Ende des Blocks für den die Variable deklariert ist
Block: durch { und } begrenzt
{ und } strukturieren ein Programm
if (…) { int i;
}
for (int i=0; ...; ...) {
}
284
{ und } strukturieren ein Programm
public static void fct(int j) { int i;
int k;
}
286Scope (Sichtbarkeitsbereich)
scope: Der Teil eines Programm in dem eine Variable sichtbar ist.
§ Variable müssen deklariert sein bevor sie sichtbar sind
§ Deklarationen müssen eindeutig sein
§ Sichtbar von Deklaration bis zum Ende des Blocks (der durch { und } angegeben wird)
§ Eine Variable die in einer for Schleife deklariert wurde kann nur im Rumpf der Schleife verwendet werden.
§ Eine Variable die in einer Methode deklariert wurde
existiert nur in der Methode.
Blöcke können geschachtelt sein
§ Loops in Methoden
§ Loops in Loops -- geschachtelte Schleifen (nested loops)
§ (In Java, Methoden können nicht in anderen Methoden geschachtelt sein.)
289
Scope (Sichtbarkeitsbereich)
public static void example() { int x = 3;
for (int i = 1; i <= 10; i++) { System.out.println(x+i);
} // i no longer exists here System.out.println(x);
} // x ceases to exist here
x's scope
i's sc op e
Scope (Sichtbarkeitsbereich)
public static void example(int x) { for (int i = 1; i <= 10; i++) {
for (int j = i; j<=10; j++) {
System.out.print(x + i + j + " ");
} // j no longer exists here System.out.println(i);
} // i no longer exists here System.out.println(x);
} // x no longer exists here
Folgen der Sichtbarkeitsregeln
§ Variable ohne überlappenden Sichtbarkeitsbereich können den selben Namen haben.
for (int i = 1; i <= 100; i++) { System.out.print("/");
}
for (int i = 1; i <= 100; i++) { // OK System.out.print("\\");
}
int i = 5; // OK: outside of loop's scope
294
Folgen der Sichtbarkeitsregeln
§ Eine Variable kann in einem Sichtbarkeitsbereich nicht mehrmals deklariert werden.
for (int i = 1; i <= 100 * line; i++) { for (int i = 2; i < line; i++) {
// ERROR: overlapping scope
// variable i is already defined in method … System.out.print("/");
}
}
Sichtbarkeitsregeln für Parameter Variable
§ Die selben Regeln gelten für Parameter Variable
Scope (Sichtbarkeitsbereich)
public static void function(int k) { int x = 3;
int y = k+x;
System.out.println(y);
} // k ceases to exist here
k's scope
y' s sc op e
Scope (Sichtbarkeitsbereich)
public static void function(int k) { int x = 3;
int y = anotherFct(k+x);
System.out.println(y);
} // k ceases to exist here
public static void anotherFct(int x) { int y= 5;
System.out.println(x+5);
}
k's scope
Warum diese Regeln
§ Lesbarkeit der Programme
§ Vereinfachung der Verwaltung des Speichers
§ Platz für eine Variable eines Basistypes muss nur in dem Block organisiert werden, in dem die Variable deklariert ist
§ Werte (die in einer Variable eines Basistypes) gespeichert werden verschwinden am Ende des Blockes
299