252-0027 Einführung in die Programmierung

Werbung
252-0027
Einführung indie Programmierung
2.5“if”-Anweisungen
2.6Nochmals Schleifen:“while”Loops
2.YOutput
ThomasR.Gross
DepartmentInformatik
ETHZürich
Uebersicht
§
2.2Typen undVariable
§ Deklaration vonVariablen
§
2.3Schleifen (Loops)
§ 2.3.1“for”Loops
§ 2.3.2Verschachtelte Schleifen
§
2.4Methoden mit Parametern
§
2.5“if”-Anweisungen
§
2.6Nochmals Schleifen
§ “while”Loops
§
2.XInput
§
2.YOutput
2
Faktorisierung für if/else Anweisungen
§ Example:
if (a == 1) {
System.out.println(a);
x = 3;
b = b + x;
} else if (a == 2) {
System.out.println(a);
x = 6;
y = y + 10;
b = b + x;
} else { // a == 3
System.out.println(a);
x = 9;
b = b + x;
}
System.out.println(a);
x = 3 * a;
if (a == 2) {
y = y + 10;
}
b = b + x;
Boolesche Ausdrücke
if (((x>0) && (y>0)) && (z > 0)) {
// block 1
}
// more code
if (((x>0) && (y>0)) && (z >= 0)) {
// block 2
}
§ Wasist andiesem CodeBeispiel schlecht?
4
Boolesche Ausdrücke
if (((x>0) && (y>0)) && (z > 0)) {
// block 1
}
// more code
if (((x>0) && (y>0)) && (z >= 0)) {
// block 2
}
§ Wasist andiesem CodeBeispiel schlecht?
§ (x>0) && (y>0) mehrfach berechnet
5
Typ boolean
§ Boolesche Werte können inVariablen desTyps boolean
gespeichert werden.
§ boolean ist ein Basistyp (primitivetype)
§ Parameterübergabe:
§ DerTyp boolean kennt nur zwei Werte:wahr (true)und
falsch (false).
§ boolean quadrant1;
§ Oderboolean quadrant1 = true;
deklarieren boolesche Variable.
Typ boolean
§ Boolesche Werte können inVariablen desTyps boolean
gespeichert werden.
§ boolean ist ein Basistyp (primitivetype)
§ Parameterübergabe:valuesemantics
§ DerTyp boolean kennt nur zwei Werte:wahr (true)und
falsch (false).
§ boolean quadrant1;
§ Oderboolean quadrant1 = true;
deklarieren boolesche Variable.
Typ boolean
§ Ein Vergleich ("test")ist ein boolescher Ausdruck (ein Ausdruck
derein boolean Ergebnis hat).
§ Ergebnis kann ineiner VariabledesTyps boolean gespeichert werden
§ Boolesche Variablekönnen mit denbooleschen Operatoren
kombiniert werden.
Boolesche Ausdrücke mit boolean Variablen
boolean quadrant1 = (x>0) && (y>0);
if (quadrant1 && (z > 0)) {
// block 1
};
// more code
if (quadrant1 && (z >= 0)) {
// block 2
}
§ Annahme:keine Aenderung vonx,y ….
11
Typ boolean Beispiele
boolean isJugendlicher = (alter < 18);
boolean wohntInZuerich = (plz >= 8000) && (plz < 8100);
// nur fuer volljaehrige aus Zuerich
if (isJugendlicher || !wohntInZuerich) {
System.out.println("Kein Zutritt!");
}
Hinweise
§ Manchmal sieht mansolchen Code(testob eine VariabledenWerttrue
hat):
if (isPrime == true) {
// schlecht
...
}
§ Dasist nicht nötig undredundant.Besser :
if (isPrime) {
...
}
// gut
Hinweise
§ Auch nicht besser ist derTestfür false:
if (isPrime == false) {
// schlecht
if (!isPrime) {
// gut
Bedingte ("short-circuit")Auswertung
§ Für && und|| müssen nicht immer beide Operanden
ausgewertet werden,umdasErgebnis zu ermitteln
§ Javabeendet dieAuswertung eines booleschen Ausdrucks
sobald dasErgebnis feststeht.
§ Ausdrücke werden vonlinksnach rechts,gemäss Präzedenz
ausgewertet
§ && stoppt sobald ein Teil(ausdruck)false ist
§ || stoppt sobald ein Teil(ausdruck) true ist
Bedingte ("short-circuit")Auswertung
§ Javabeendet dieAuswertung eines booleschen Ausdrucks
sobald dasErgebnis feststeht.
§ Ausdrücke werden vonlinksnach rechts,gemäss Präzedenz
ausgewertet
§ && stoppt sobald ein Teil(ausdruck)false ist
§ || stoppt sobald ein Teil(ausdruck) true ist
§ Diese ArtderAuswertung heisst bedingte Auswertung
§ Folgende Teilausdrücke werden abhängig vonzuerst ausgewerteten
Ausdrücken (nicht)evaluiert
Auswertung desTests
§ Wir wollen nur Quotienten (für a,b)grösser als 0drucken:
Scanner console = new Scanner(System.in);
System.out.print("Eingabe zweier Zahlen: ");
int a = console.nextInt();
int b = console.nextInt();
System.out.println(a + " / " + b + " = " + a/b);
...
Auswertung desTests
§ Viele "if"Statementsmachen denCodeunlesbar
Scanner console = new Scanner(System.in);
System.out.print("Eingabe zwei Zahlen: ");
int a = console.nextInt();
int b = console.nextInt();
if ( b!=0) {
if ( a/b>0 ) {
System.out.println(a + " / " + b + " = " + a/b);
};
}
...
Auswertung desTests
§ Wir wollen nur Quotienten (für a,b)grösser als 0drucken:
Scanner console = new Scanner(System.in);
System.out.print("Eingabe zweier Zahlen: ");
int a = console.nextInt();
int b = console.nextInt();
// a/b > 0 UND
// b != 0
System.out.println(a + " / " + b + " = " + a/b);
}
...
Reihenfolge ist wichtig
§ Dieser Codeführt zu einer Fehlermeldung wenn b==0:
// Warning.
Scanner console = new Scanner(System.in);
System.out.print("Eingabe zweier Zahlen: ");
int a = console.nextInt();
int b = console.nextInt();
if (a/b>0) && (b!=0) {
System.out.println(a + " / " + b + " = " + a/b);
};
}
...
Bedingte ("short-circuit")Auswertung
§ Dieser Codeführt zu keiner Fehlermeldung wenn b==0:
// Now there is no problem
Scanner console = new Scanner(System.in);
System.out.print("Eingabe zweier Zahlen: ");
int a = console.nextInt();
int b = console.nextInt();
if (b!=0) && (a/b>0) {
System.out.println(a + " / " + b + " = " + a/b);
};
}
...
38
40
DeMorgan'sRegeln
DeMorgan'sRegeln:Regeln für dieNegationboolescher Ausdrücke.
§ Praktisch wenn mandasGegenteil eines Ausdrucks braucht.
Ursprünglicher Ausdruck
Negierter Ausdruck
Alternative
a && b
a || b
!a || !b
!a && !b
!(a && b)
!(a || b)
§ Beispiel:
Original
if (x == 7 && y > 3) {
Negiert
if (x != 7 || y <= 3) {
...
}
...
}
2.5Nochmals Schleifen
§ Bisher:Obergrenze für Schleifenzähler standzu Beginn der
Schleife fest
§ Jetzt:mehr Flexibilität
§ Korrekte Terminierung wichtig
43
Eine triviale Aufgabe ...
§ Schreiben Sie eine Methode printNumbers diedieZahlen
von1bis Ndurch Komma getrennt ausgibt.
Beispiel:
Obergrenze N eingeben:
sollte ergeben:
1, 2, 3, 4, 5
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
}
Outputbei 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
}
Outputbei Eingabe 5: , 1, 2, 3, 4, 5
Gartenzaun Analogie
§ Wir geben n Zahlen aus aber brauchen nur n - 1Kommas.
§ Aehnlich dem Bau eines Weidezaunes mit Pfosten und
Querstreben
§ Wenn wir - wie inder1.fehlerhaften Lösung – Pfosten undStreben
installieren dann hatderletzte Pfosten inderLuft hängende Streben.
for(Laenge desZauns){
Betoniere Pfosten.
Installiere Querstreben.
}
Schleife
§ Fügen Sie eine Anweisung ausserhalb derSchleife hinzu um
denersten "Pfosten"zu plazieren
Betoniere Pfosten.
for(Laenge desZauns - 1){
Installiere Querstreben.
Betoniere Pfosten.
}
Lösungen basierend aufdieser 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 dieSchleife kann verändert werden:
for (int i = 1; i <= max - 1; i++) {
System.out.print(i + ", ");
}
System.out.println(max); // to end the line
"off-by-one"Error(Um-Eins-daneben-Fehler)
§ DieSchleife wurde einmal zuviel (oder einmal zuwenig)
durchlaufen.
§ "Zaunpfahlproblem"– es gibt sogar eine DWikipediaSeite
(Inhalt ohne Gewähr)
50
Terminierung vonLoops
§ Verwandeln Sie dieMethode printNumbers ineine neue
Methode printPrimes diealle Primzahlen bis zur
Obergrenze maxausgibt.
§ Beispiel:printPrimes mit Eingabe 50ergibt:
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 ingenau zwei Faktoren zerlegt werden:p
und1
53
// Prints all prime numbers up to the given max.
publicstaticvoidmain(String[]args){
Scannerconsole=newScanner(System.in);
Beispiellösung
System.out.print("Inputmax:");
intmax=console.nextInt();
//Printsallprimenumbersuptothegivenmax.
if(max>=2){
System.out.print("2");
for(inti=3;i<=max;i++){
if(isPrime(i,max)){
System.out.print(","+i);
}
}
}
}
System.out.println();
//isPrimereturnstrueifiisprime
56
while Schleifen
Klassifizierung vonSchleifen
§ bestimmte Schleife (definiteloop):Anzahl derAusführungen
desRumpfes ist vorher bekannt.
§ Diefor Schleifen waren bisher immer bestimmte Schleifen.
§ Drucke "hello"10-mal.
§ Finden Sie alle Primzahlen <einer ganzen Zahl n.
§ Drucken Sie jede ungerade Zahl zwischen 7und91.
§ unbestimmte Schleife (indefiniteloop):Anzahl der
Ausführungen desRumpfes ist nicht vorher bekannt.
Klassifizierung vonSchleifen
§ unbestimmte Schleife (indefiniteloop):Anzahl der
Ausführungen desRumpfes ist nicht vorher bekannt.
§ Lesen Sie denInputvonderKonsole bis derBenutzer eine nichtnegativeganze Zahl eingibt.
§ Wiederholen Sie bis derBenutzer ein "q"eingegeben hat.
§ Lesen Sie eine Datei bis drei aufeinanderfolgende Sätze mit einem
"!"enden.
§ Nehmen Sie Beiträge (viacrowdfunding)entgegen bis dasZiel
erreicht ist.
Diewhile Schleife
§ while Schleife:Führen Sie denSchleifenrumpf solange aus wie
derboolesche Ausdruck test denWerttrue 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
// initialization
// test
// update
Diewhile Schleife
§ while Schleife:Führen Sie denSchleifenrumpf solange aus wie
derboolesche Ausdruck test denWerttrue ergibt.
while (test) {
statement(s);
}
nein
ja
Ist testwahr?
§ 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
Loopausfuehren
Anweisung nach
Loopausfuehren
62
Beispiellösung
public static boolean isPrime (int arg, int max){
// 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);
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 oftwir den
Zähler erhöhen müssen umden1.Faktor zu finden
Werte dieHinweise sind …
§ Hinweiszeichen (Sentinel)("sentinel"):Ein WertderdasEnde
eine Reihe anzeigt
§ sentinelloop:Schleife deren Rumpf ausgeführt wird bis ein Sentinel
gesehen wurde
§ Beispiel:Ein Programm soll Zahlen einlesen bis derBenutzer
eine 0eingibt;dann soll dieSumme aller eingegebenen Zahlen
ausgegeben werden.
§ (Indiesem Beispiel ist 0dasHinweiszeichen/derSentinel.)
Werte dieHinweise sind …
§ Beispiel:Ein Programm soll Zahlen einlesen bis derBenutzer
eine 0eingibt;dann soll dieSumme aller eingegebenen Zahlen
ausgegeben werden.
§ (Indiesem Beispiel ist 0dasHinweiszeichen/derSentinel.)
Enter a
Enter a
Enter a
Enter a
The sum
number
number
number
number
is 60
(0
(0
(0
(0
to
to
to
to
quit):
quit):
quit):
quit):
10
20
30
0
Fehlerhafte Lösung
§ Wasist andiesem 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);
Ein anderes Hinweiszeichen …
§ Aendern Sie dasProgramm sodass -1derSentinelist.
§ Examplelogofexecution:
Enter a number (-1
Enter a number (-1
Enter a number (-1
Enter a number (-1
Enter a number (-1
The total is 80
to
to
to
to
to
quit):
quit):
quit):
quit):
quit):
15
25
10
30
-1
Ein anderes Hinweiszeichen …
§ Setzen Sie denSentinelauf-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 dasResultfalsch.Warum?
The total was 79
DasProblemmit diesem Programm
§ UnserProgramm folgt diesem Muster:
summe =0.
while(inputist nicht dersentinel){
drucke prompt;leseinput.
addiere inputzu summe.
}
§ Beim letzten Durchlauf durch denRumpf wird derSentinel-1
zur Summe addiert:
DasProblemmit diesem Programm
§ Beim letzten Durchlauf durch denRumpf wird derSentinel-1
zur Summe addiert:
drucke prompt;leseinput(-1).
addiere input(-1)zu summe.
§ Beispiel inkorrekter Terminierung (off-by-oneerror,
Zaunpfahlproblem):
§ Müssen N Zahlen lesen aber nur dieersten N-1addieren.
Lösung
summe =0.
drucke prompt;leseinput.
while(inputist nicht dersentinel){
addiere inputzu summe.
drucke prompt;leseinput.
}
//setzen eines pfostens
//installationquerstrebe
//setzen eines pfostens
§ Schleifen mit einem Sentinelfolgen oftdiesem Muster.
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 dentestamEnde desSchleifenrumpfes aus
umzu entscheiden,ob ein weiterer Durchlauf nötig ist
§ Stellt sicher dass derRumpf { … } mindestens einmal ausgeführt wird.
Anweisung(en)im
Loopausfuehren
do {
statement(s);
} while (test);
Ist testwahr?
nein
Anweisung nach
Loopausfuehren
ja
do/while Schleife
Nochmal Beispiel
// Add numbers till -1 is entered
Scanner console = new Scanner(System.in);
int sum = 0;
Anweisung(en)im
Loopausfuehren
Ist testwahr?
nein
// first round nothing to add
int number = 0;
Anweisung nach
Loopausfuehren
do {
sum = sum + number;
System.out.print("Enter a number (-1 to quit): ");
number = console.nextInt();
} while (number != -1);
System.out.println("The total is " + sum);
ja
Herunterladen