252-0027 EinführungindieProgrammierungI 2.6if-Anweisungen ThomasR.Gross DepartmentInforma?k ETHZürich Uebersicht ! 2.6"if"Anweisungen ! 2.7NochmalSchleifen 2 ifAnweisung("if-statement") ! FührteineAnweisung(oderAnweisungen)nurauswennein TestdenWertwahr("true")ergibt. if (test) { statement; ... statement; } ! Beispiel: nein Isttestwahr? ja Anweisung(en) ausführen FolgendeAnweisung ausführen double punkte = console.nextDouble(); if (punkte >= 50.0) { System.out.println("Pruefung bestanden."); } if-elseAnweisung ! FührteinenGruppevonAnweisungenauswenneinTestdenWertwahr ("true")ergibt,sonsteineandereGruppe if (test) { nein ja statement(s); Isttestwahr? } else { statement(s); "else"Anweisung(en) "if"Anweisung(en) ausführen ausführen } ! Beispiel: FolgendeAnweisung double punkte = console.nextDouble(); ausführen if (punkte >= 50.0) { System.out.println("Pruefung bestanden."); } else { System.out.println("Pruefung nicht bestanden."); } BoolescheAusdrücke ! ifAnweisungenundforSchleifenverwendenbeide boolescheAusdrücke. for (int i = 1; i <= 10; i++) { ... if (i <= 10) { ... ! DieseAusdrückewerdenausgewertet---Ergebnis entweder"true"oder"false" ! VerwendenVergleichsoperatoren Vergleichsoperatoren Operator Meaning Example Value == gleich 1 + 1 == 2 true != ungleich 3.2 != 2.5 true < wenigerals 10 < 5 false > grösserals 10 > 5 true <= wenigeralsodergleich 126 <= 100 false >= grösseralsodergleich 5.0 >= 5.0 true Vorsicht:nichtalleOperatorenkönnenfüralleTypen(sinnvoll) angewendetwerden. Gebrauchvonif WasfälltIhnenindiesemCodeBeispielauf? Scanner console = new Scanner(System.in); System.out.print("Wieviele Punkte haben Sie erreicht? "); int percent = console.nextInt(); if (percent >= 90) { System.out.println("Ihre Note ist 6.0."); } if (percent >= 80) { System.out.println("Ihre Note ist 5.0."); } if (percent >= 70) { System.out.println("Ihre Note ist 4.0."); } if (percent >= 60) { System.out.println("Ihre Note ist 3.5."); } if (percent < 60) { System.out.println("Ihre Note ist 3.0."); } ... Verschachtelteif-else Anweisungen AuswahlbesVmmtdurchmehrereTests if (test) { statement(s); } else if (test) { statement(s); } else { statement(s); } nein ja Ergibttest1wahr? nein Ergibttest2wahr? Gruppe3Anweisungenausführen ja Gruppe1Anweisungenausführen Gruppe2Anweisungenausführen FolgendeAnweisung ausführen Verschachtelteif-else Anweisungen Beispiel: if (x > 0) { System.out.println("Positiv"); } else if (x < 0) { nein ja Ergibttestwahr? Gruppe1Anweinein ja System.out.println("Negativ"); Ergibttestwahr? sungenausführen } else { Gruppe2AnweiSystem.out.println("Null"); Gruppe3Anweisungenausführen sungenausführen } FolgendeAnweisung ausführen 15 VerschachtelteifKonstrukte • Genau ein 1 Pfad (gegenseitiger Ausschluss) • if (test) { statement(s); } else if (test) { statement(s); } else { statement(s); } • 0 oder 1 Pfad (gegenseitiger Ausschluss) if (test) { statement(s); } else if (test) { statement(s); } else if (test) { statement(s); } 0, 1, oder viele Pfade (unabhängig, keine gegenseitiger Ausschluss) if (test) { statement(s); } if (test) { statement(s); } if (test) { statement(s); } Welcheif/else KombinaVon? (1)if/if/if (2)verschachtelteif/else(3)verschachtelteif/else/if ! Ob–abhängigvonfrüherenRennen–jemandinderersten,zweiten,oderdri^enGruppestartet. ! (2) ! ObeseineMedaille(Notendurschni^≥5.9)odereineUrkunde(5.75-5.9)gibt. ! (3) ! verschachtelteif / else if ObeineZahldurch2,3,und/oder5teilbarist. ! (1) ! verschachtelteif / else if / else Folgevonif / if / if Note(auf0.25gerundet)aufgrundderPunkte(Prozent)inderPrüfung. ! (2) verschachtelteif / else if / else if / else if / else Verschachtelteif/elseBeispiel FormelfürBody-Mass-Index(BMI): BMI < 18.5 18.5 – <25 25.0 -- <30 ≥ 30.0 Weight class Untergewicht Normalgewicht Uebergewicht Adipositas ! SchreibenSieeinProgrammdasfolgendenOutputproduziert: Dieses Programm erhebt die Daten fuer 2 Personen und berechnet den Body-Mass-Index(BMI). Geben Sie die Daten fuer die naechste Person ein: Laenge(in m)? 1.70 Masse(in kg)? 60 Geben Sie die Daten fuer die naechste Person ein: Laenge(in m)? 1.65 Masse(in kg)? 75 Verschachtelteif/elseBeispiel FormelfürBody-Mass-Index(BMI): BMI < 18.5 18.5 – <25 25.0 -- <30 ≥ 30.0 Weight class Untergewicht Normalgewicht Uebergewicht Adipositas ! SchreibenSieeinProgrammdasfolgendenOutputproduziert: Dieses Programm erhebt die Daten fuer 2 Personen und berechnet den Body-Mass-Index(BMI). Person 1 BMI = 20.761245674740484 Normalgewicht Person 2 BMI = 27.548209366391184 Uebergewicht Differenz = 6.786963691650700 Nestedif/else System.out.println("Person " + number + " BMI = " + bmi); if (bmi < 18.5) { System.out.println(" Untergewicht "); } else if (bmi < 25) { System.out.println(" Normalgewicht "); } else if (bmi < 30) { System.out.println(" Uebergewicht "); } else { System.out.println(" Adipositas "); } BoolescheOperatoren ! VergleichekönnendurchboolescheOperatorenverknüpgwerden Operator Description Example Result && and (2 == 3) && (-1 < 5) false || or (2 == 3) || (-1 < 5) true ! not !(2 == 3) true ! ”Wahrheitstabelle"fürdieseOperatoren,fürAussagenpundq: p q p && q true true true false false false true true false false false false p || q true p !p true true false true false true false BoolescheAusdrücke ! VergleichsoperatorenhabeneineVeferePräzedenzalsarithmeVsche Operatoren. 5 * 7 5 * 7 35 35 true >= >= >= >= 3 + 5 * (7 - 1) 3 + 5 * 6 3 + 30 33 ! Vergleichsoperatorenkönnennichteine“Ke^e”bildenwieinMathemaVk 2 <= x <= 10 true <= 10 error! (Annahme:xist15) BoolescheAusdrücke ! Aussagenkönnenmit&&oder||kombiniertwerden 2 <= x && x <= 10 true && false false (Annahme:xist15) ! BoolescheOperatorenhabeneineVeferePräzedenzals Vergleichsoperatoren. ! VerwendenSieKlammernumKlarheitzuschaffen Beispiel ! WelcherboolescheAusdruckergibttrue wenneinJahr jahr einSchaltjahrist? ! jahr istSchaltjahrwennjahr durch4teilbarist(ohneRest),jahr abernichtdurch100ohneRestteilbarist,esseidenndassjahr ohne Restdurch400teilbarsei. ! int jahr; // aktuelles Jahr ! jahr % 4 == 0 && jahr % 100 != 0 || jahr % 400 == 0 29 Beispiel ! WelcherboolescheAusdruckergibttrue wenneinJahr jahr einSchaltjahrist? ! jahr istSchaltjahrwennjahr durch4teilbarist(ohneRest),jahr abernichtdurch100ohneRestteilbarist,esseidenndassjahr ohne Restdurch400teilbarsei. ! int jahr; // aktuelles Jahr ! jahr % 4 == 0 && jahr % 100 != 0 || jahr % 400 == 0 ! BessermitKlammern: ((jahr % 4 == 0) && (jahr % 100 != 0)) || (jahr % 400 == 0) 30 BoolescheAusdrücke ! WasistdasErgebnisfürdiefolgendenAusdrücke? int x = 42; int y = 17; int z = 25; ! ! ! ! ! y < x && y <= z x % 2 == y % 2 || x % 2 == z % 2 x <= y + z && x >= y + z !(x < y && x < z) (x + y) % 2 == 0 || !((z - y) % 2 == 0) ! Answers:true,false,true,true,false Faktorisierung ! SieerinnernsichandieZerlegungeinerZahlinPrimzahlen ! OderdieZerlegungvonPolynomen ! Faktorisierung ! Idee:keineUeberlappung ! Faktorisierung(factoring)vonCode:Herausarbeitenvon gemeinsamen/redundantenAnweisungen ! InderPraxisofRefaktorisierung(refactoring) Faktorisierungfürif/elseAnweisungen ! 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; BoolescheAusdrücke if (((x>0) && (y>0)) && (z > 0)) { // block 1 } // more code if (((x>0) && (y>0)) && (z >= 0)) { // block 2 } ! WasistandiesemCodeBeispielschlecht? ! (x>0) && (y>0) mehrfachberechnet 40 Typboolean ! BoolescheWertekönneninVariablendesTypsboolean gespeichertwerden. ! DerTypbooleankenntnurzweiWerte:wahr(true)und falsch(false). ! EinVergleich("test")isteineinfacherboolescherAusdruck(ein AusdruckdereinbooleanErgebnishat). ! BoolescheAusdrückekönnenmitdenbooleschenOperatorenkombiniert werden. ! boolean quadrant1; oderboolean quadrant1 = true; deklarierenboolescheVariable. TypbooleanBeispiele boolean isJugendlicher = (alter < 18); boolean wohntInZuerich = (plz >= 8000) && (plz < 8100); boolean studiertETH = true; // nur fuer volljaehrige/n Student/in aus Zuerich if (isJugendlicher || !wohntInZuerich || !studiertETH) { System.out.println("Kein Zutritt!"); } Gebrauchvonboolean ! KannErgebniseineskompliziertenAusdrucksspeichernundspäter wiederverwenden ! VorausgesetztdieKomponentenändernsichnicht… ! MachtProgrammlesbarer Hinweise ! ManchmalsiehtmansolchenCode(testobeineVariableden Werttruehat): if (isPrime == true) { ... } // schlecht ! DasistnichtnöVgundredundant.Besser: if (isPrime) { ... } // gut Hinweise ! AuchnichtbesseristderTestfürfalse: if (isPrime == false) { // schlecht if (!isPrime) { // gut Bedingte("short-circuit")Auswertung ! Für&&und||müssennichtimmerbeideOperanden ausgewertetwerden,umdasErgebniszuermi^eln ! JavabeendetdieAuswertungeinesbooleschenAusdrucks sobalddasErgebnisfeststeht. Bedingte("short-circuit")Auswertung ! Für&&und||müssennichtimmerbeideOperanden ausgewertetwerden,umdasErgebniszuermi^eln ! JavabeendetdieAuswertungeinesbooleschenAusdrucks sobalddasErgebnisfeststeht. ! Ausdrückewerdenvonlinksnachrechts,gemässPräzedenz ausgewertet ! &&stopptsobaldeinTeil(ausdruck)false ist ! ||stopptsobaldeinTeil(ausdruck)true ist Bedingte("short-circuit")Auswertung ! JavabeendetdieAuswertungeinesbooleschenAusdrucks sobalddasErgebnisfeststeht. ! Ausdrückewerdenvonlinksnachrechts,gemässPräzedenz ausgewertet ! &&stopptsobaldeinTeil(ausdruck)false ist ! ||stopptsobaldeinTeil(ausdruck)true ist ! DieseArtderAuswertungheisstbedingteAuswertung ! FolgendeTeilausdrückewerdenabhängigvonzuerstausgewerteten Ausdrücken(nicht)evaluiert 61 Bedingte("short-circuit")Auswertung ! DieserCodeführtzueinemout-of-boundsFehlerfallsarray1oder array2wenigerals2Elementehat // tests if array1 and array2 end with the same two ints. boolean last2Equal; int a1_len = array1.length; int a2_len = array2.length last2Equal = ((array1[a1_len-1] == array2[a2_len-1]) && (array1[a1_len-2] == array2[a2_len-1])); ! DieserCodeführtzukeinemFehler: last2Equal = ((( a1_len > 1) && (a2_len > 1)) && ((array1[a1_len-1] == array2[a2_len-1]) && (array1[a1_len-2] == array2[a2_len-2]))); BedingteAuswertung:Vorsicht ! WassinddieWertevoniundjamEndedesCodesegments? // look closely int i = 0; int j = 0; if ((j !=0) && (i++ > 0) { System.out.println(…); } ! Vorsichtbei++/-- DeMorgan'sRegeln DeMorgan'sRegeln:RegelnfürdieNegaVonboolescherAusdrücke. ! PrakVschwennmandasGegenteileinesAusdrucksbraucht. UrsprünglicherAusdruck NegierterAusdruck Alterna?ve 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.7Schleifen ! Bisher:ObergrenzefürSchleifenzählerstandzuBeginnder Schleifefest ! Jetzt:mehrFlexibilität ! KorrekteTerminierungwichVg 66 EinetrivialeAufgabe... ! SchreibenSieeineMethodeprintNumbersdiedieZahlen von1bisNdurchKommagetrenntausgibt. Beispiel: Obergrenze N eingeben: sollteergeben: 1, 2, 3, 4, 5 5 FehlerhageLö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 } OutputbeiEingabe5: 1, 2, 3, 4, 5, FehlerhageLö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 } OutputbeiEingabe5: , 1, 2, 3, 4, 5 GartenzaunAnalogie ! WirgebennZahlenausaberbrauchennurn-1Kommas. ! AehnlichdemBaueinesWeidezaunesmitPfostenund Querstreben ! Wennwir-wieinder1.fehlerhagenLösung–PfostenundStreben installierendannhatderletztePfosteninderLughängendeStreben. for(LaengedesZauns){ BetonierePfosten. InstalliereQuerstreben. } Schleife ! FügenSieeineAnweisungausserhalbderSchleifehinzuum denersten"Pfosten"zuplazieren BetonierePfosten. for(LaengedesZauns-1){ InstalliereQuerstreben. BetonierePfosten. } LösungenbasierendaufdieserIdee System.out.print(1); for (int i = 2; i <= max; i++) { System.out.print(", " + i); } System.out.println(); // to end the line AlternaVve:1.oderletzterDurchlaufdurchdieSchleifekannverä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) ! DieSchleifewurdeeinmalzuviel(odereinmalzuwenig) durchlaufen. ! "Zaunpfahlproblem"–esgibtsogareineDWikipediaSeite (InhaltohneGewähr) 73 TerminierungvonLoops ! VerwandelnSiedieMethodeprintNumbersineineneue MethodeprintPrimesdieallePrimzahlenbiszur Obergrenzemaxausgibt. ! Beispiel:printPrimes mitEingabe50ergibt: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47 ! Wennmax<2,gebenichtsaus. ! EinePrimzahlpkanningenauzweiFaktorenzerlegtwerden:p und1 // Prints all prime numbers up to the given max. public static void main (String[] args) { Scanner console = new Scanner(System.in); System.out.print("Input max: "); int max = console.nextInt(); Beispiellösung // Prints all prime numbers up to the given max. if (max >= 2) { System.out.print("2"); for (int i = 3; i <= max; i++) { // Determine how many factors the given number has. int count =0; for (int j = 1; j<=max; j++) { if (i % j == 0) { count++; } } if (count == 2) { System.out.print(", " + i); } } } } System.out.println(); whileSchleifen KlassifizierungvonSchleifen ! bes?mmteSchleife(definiteloop):AnzahlderAusführungen desRumpfesistvorherbekannt. ! DieforSchleifenwarenbisherimmerbesVmmteSchleifen. ! Drucke"hello"10-mal. ! FindenSieallePrimzahlen<einerganzenZahln. ! DruckenSiejedeungeradeZahlzwischen7und91. ! unbes?mmteSchleife(indefiniteloop):Anzahlder AusführungendesRumpfesistnichtvorherbekannt. KlassifizierungvonSchleifen ! unbes?mmteSchleife(indefiniteloop):Anzahlder AusführungendesRumpfesistnichtvorherbekannt. ! LesenSiedenInputvonderKonsolebisderBenutzereinenichtnegaVveganzeZahleingibt. ! WiederholenSiebisderBenutzerein"q"eingegebenhat. ! LesenSieeineDateibisdreiaufeinanderfolgendeSätzemiteinem "!"enden. ! NehmenSieBeiträge(viacrowdfunding)entgegenbisdasZiel erreichtist. DiewhileSchleife ! whileSchleife:FührenSiedenSchleifenrumpfsolangeaus wiederboolescheAusdrucktestdenWerttrueergibt. 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 DiewhileSchleife ! whileSchleife:FührenSiedenSchleifenrumpfsolangeaus wiederboolescheAusdrucktestdenWerttrueergibt. while (test) { statement(s); } nein ja Isttestwahr? Anweisung(en)im Loopausfuehren ! Beispiel: int num = 1; while (num*num <= 2000) { System.out.print(num + " "); num = num * 2; } // output: 1 2 4 8 16 32 Anweisungnach Loopausfuehren 81 BeispielwhileSchleife // 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 ! whileisthierbessseralsforweilwirnichtwissenwieogwirden Zählererhöhenmüssenumden1.Faktorzufinden WertedieHinweisesind… ! Hinweiszeichen(Sen?nel)("sen?nel"):EinWertderdasEnde eineReiheanzeigt ! sen?nelloop:SchleifederenRumpfausgeführtwirdbiseinSenVnel gesehenwurde ! Beispiel:EinProgrammsollZahleneinlesenbisderBenutzer eine0eingibt;dannsolldieSummeallereingegebenenZahlen ausgegebenwerden. ! (IndiesemBeispielist0dasHinweiszeichen/derSenVnel.) WertedieHinweisesind… ! Beispiel:EinProgrammsollZahleneinlesenbisderBenutzer eine0eingibt;dannsolldieSummeallereingegebenenZahlen ausgegebenwerden. ! (IndiesemBeispielist0dasHinweiszeichen/derSenVnel.) 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 FehlerhageLösung ! WasistandiesemProgrammfalsch? 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); EinanderesHinweiszeichen… ! AendernSiedasProgrammsodass-1derSenVnelist. ! ExamplelogofexecuVon: 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 EinanderesHinweiszeichen… ! SetzenSiedenSenVnelauf-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); ! JetztistdasResultfalsch.Warum? The total was 79 DasProblemmitdiesemProgramm ! UnserProgrammfolgtdiesemMuster: summe=0. while(inputistnichtdersenMnel){ druckeprompt;leseinput. addiereinputzusumme. } ! BeimletztenDurchlaufdurchdenRumpfwirdderSenVnel-1 zurSummeaddiert: DasProblemmitdiesemProgramm ! BeimletztenDurchlaufdurchdenRumpfwirdderSenVnel-1 zurSummeaddiert: druckeprompt;leseinput(-1). addiereinput(-1)zusumme. ! BeispielinkorrekterTerminierung(off-by-oneerror, Zaunpfahlproblem): ! MüssenNZahlenlesenabernurdieerstenN-1addieren. Lösung summe=0. druckeprompt;leseinput. while(inputistnichtdersenMnel){ addiereinputzusumme. druckeprompt;leseinput. } //setzeneinespfostens //installaMonquerstrebe //setzeneinespfostens ! SchleifenmiteinemSenVnelfolgenogdiesemMuster. BeispielmitSenVnel 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/whileSchleife ! do/whileSchleife:FührtdentestamEndedesSchleifenrumpfesaus umzuentscheiden,obeinweitererDurchlaufnöVgist ! StelltsicherdassderRumpf{ … }mindestenseinmalausgeführtwird. do { statement(s); } while (test); Anweisung(en)im Loopausfuehren Isttestwahr? nein Anweisungnach Loopausfuehren ja do/whileSchleife ! 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 Loopausfuehren Isttestwahr? nein Anweisungnach Loopausfuehren ja