Übungsstunde 4 Woche 3 – 06.10. – 10.10. - Gruppe G Ablauf Übungsstunde 4 › Feedback Serie 3 (Code) und 2 (Theorie) › Theorie und Übungen › Tipps zur Serie 4 Fragen: Jederzeit und überall Theorie und Beispiele 1 Scopes Scopes › Anwendungsbereich einer Variable › Definiert wo im Programm(code) eine Variable gültig ist. › Unterteilt in Blöcke mit { … } › Faustregelen: Variablen sind gültig ab ihrer Definition, bis zum Ende des Blockes in dem sie definiert wurden. Beispiel: int sum = 0; for (int i = 0; i < 5; ++i) { sum += i; std::cout << i << "\n"; // Outputs i } if (sum < 0) { Scope b int b = 0; } std::cout << sum; std::cout << i; std::cout << b; Scope sum Scope i Theorie und Beispiele Loops – Do-while – break-continue Der while Loop Kernidee des while Loops: Führe eine Operation aus, solange während eine Bedingung erfüllt ist. Notation: while ( condition ) { Anweisung(en) } › Oft: Anzahl der Exekutionen im Vornhinein unklar Der do-while Loop Sehr ähnlich wie der while Loop Unterschied: Body wird erst einmal ausgeführt bevor die Bedingung geprüft wird Notation: do { Anweisung(en) } while ( condition ); //Achtung ; nicht vergessen do-while: «Tue Anweisungen, wiederhole während … gilt.» while: «Während … gilt, wiederhole Anweisungen.» Welcher Loop wann? Grundsätzlich könnte immer jeder Loop verwendet werden. Entscheide auf Grund von: › Code länge: Kürzer ist besser! › Lesbarkeit: Je verständlicher desto besser! Ausserdem gibt es hinter jedem Loop eine Kernidee, die oft auf eine spezifische Situation zutrifft. Welcher Loop wann? Loop Was for Es wird etwas abgezählt. Der Zähler betrifft nur die Schlaufe. Beispiele: - Führe eine Operation n mal aus - Führe eine Operation für alle Zahlen von 1 – n aus - Führe eine Operation für alle Elemente in einer Liste aus (bald) while Operation auf einer zuvor definierten Variable. Oft ist das Ziel bekannt, der «Aufwand» (Anzahl nötiger Wiederholungen) aber nicht. Beispiele: - Teile ein Zahl durch 2 bis sie 0 ist - Führe eine Annäherung aus bis sich der Rest nicht mehr verändert (extrem typisch in der Numerik!) do Bedingung hängt von einer Variable ab, die erst im Body auftaucht/definiert wird. Beispiel: - Lese Input ein, bis eine bestimmte Bedingung erfüllt ist. Korrektheit - Probleme int main () { std::cout << "Enter a number: "; int n; std::cin >> n; for (int i = 1; i <= n; ++i) std::cout << i << "\n"; int i = 0; while (i < n) std::cout << ++i << "\n"; i = 1; do std::cout << i++ << "\n"; while (i <= n); return 0; } Printe alle Zahlen von 1 bis n for: Korrekt, ausser n ist int max while: Korrekt do: Falsch wenn n < 1oder n int max Übungsbeispiel 1 (Basisprüfung Winter ‘11) Wie oft wird der Rumpf/Body der folgenden Schleife ausgeführt? int n = 16; while ((n /= 2) > 0) { ++n; } Lösung: unnedlich – ist n==2 wird daraus n==1 in der Bedingung (/=2) und wieder 2 im Rumpf... Übungsbeispiel 2 (Basisprüfung Winter ‘11) Was ist die Ausgabe des folgenden Codes? for (int i = 0; i < 16; i += 3) { if (i % 2 != 0) std::cout << i; } Lösung: 3 9 15 (genauer 3915) Übungsbeispiel 3 (~Basisprüfung Winter ‘12) Was ist die Ausgabe des folgenden Codes? Durchgang int i=1; 1 int j=1; 2 do { 3 4 std::cout << i << " "; 5 j+=2; 6 i+=j; 7 8 } while (i<=100) Lösung: 1 4 9 16 25 36 49 64 81 100 i j 1 1 4 3 9 5 16 7 25 9 36 11 49 13 64 15 9 81 17 10 100 19 Break und Continue › Beeinflussen jeweils den innersten for/while/do loop › Break: Bricht den Loop komplett ab und führt das Programm nach dem Loop fort › Continue: Springt direkt zum Ende des Rumpfes des Loops und startet die nächste Loop-Iteration (sofern noch eine vorhanden) › Beispiel: Primzahlen von 3 – 100 Idee: – Für jede Zahl i zwischen 3 und 100 teste ob sie einen Teiler zwischen 2 und i-1 hat – Sobald ein Teiler gefunden wird ist es keine Primzahl – Erweiterung: Überspringe ungerade Zahlen Achtung: Das Beispiel könnte man deutlich schöner machen! Break Beispiel – Finde Primzahlen 3 - 100 int main() { bool teiler; for (int i = 3 i <= 100; ++i) { teiler = false; for (int k = 2; x < i; ++k) { if (i%k == 0) { teiler = true; break; } } if (!teiler) std::cout << i << " "; } return 0; } Continue Beispiel – Finde Primzahlen 3 - 100 int main() { bool teiler; for (int i = 3; i <= 100; ++i) { if (i%2 == 0) continue; teiler = false; for (int k = 2; x < i; ++k) { if (i%k == 0) { teiler = true; break; } } if (!teiler) std::cout << i << " "; } return 0; } Theorie und Beispiele Gleitkommazahlen und Konvertierung Floating point numbers (Floats) › Auf Deutsch: Gleitkommazahlen › Zwei Typen in C++: float und double › Floating/Gleitend: – Das Komma ist nicht fest, sondern wird durch eine Potenz gesetzt. – Sehr grosser Wertebereich (auch negativ): › Float: 1.17549 * 10-38 – 3.40282*1038 › Double: 2.22507 * 10-308 – 1.79769*10308 › Als Vergleich: – Planck Länge: 1.62 * 10−35 m – Ungefährer Durchmesser des sichtbaren Universums: 8.7 * 1026 m Floating point number system Ein endliches Gleitkommazahlensystem ist eine endliche Teilmenge von ℝ definiert wie folgt: ℱ ( 𝛽, 𝑝, 𝑒𝑚𝑖𝑛 , 𝑒𝑚𝑎𝑥 ) Mit: 𝛽 = Basis (float/double: 2) 𝑝 = Präzision (float: 24, double: 53) 𝑒𝑚𝑖𝑛 = kleinster Exponent (float: -126, double: -1022) 𝑒𝑚𝑎𝑥 = grösster Exponent (float: 127, double: 1023) Praktischer Umgang mit floats › Floats sind diskret, nicht jede Zahl lässt sich darstellen Niemals float/double in Gleichheitsbedingung verwenden › Auch Ganzzahlen können als double/float geschrieben werden: double a = 7; // a wird 7 im Typ double sein x * 5.0; // 5 wird als double interpretiert y / 4.0f // 4 wird als float interpretiert «Normale» Division › Computer sind gut mit floats… Konvertierung bool ≺ int ≺ unsigned int ≺ float ≺ double › Von links nach rechts: Konvertierung › Von rechts nach links: truncate › Implizit (gemischte Audrücke) oder explizit › Type casting (explizite Konvertierung) – Type (expr) – int (1.6) // projeziert double 1.6 auf int 1 – Float (2) // projeziert int 2 auf float 2.0f Kleine Übung › Sei int x = 1; Bestimme Wert, Typ und Ausdrucksart (L/R): a) 1 + true == 2 b) 3 % 2 + 1.0 * 4 c) x = 10 / 2 / 5 / 2 d) x / 2.0 e) 1f + x++ f) double a = 5/3; Übung Darstellung vonn floats Berechne den Wert der Variable d nach der Zuweisung: Float d = 0.1; Lösung: 0.100000001490116119384765625 Theorie und Beispiele Asserts Assertions › Zu Deutsch: Behauptung › Statements die helfen korrekte Programme zu schreiben. › Helfen Fehler zu finden. › In C++: – Mit Hile von cassert: #include <cassert> – Brechen das Programm ab wenn falsch › Achtung: Asserts sind als Hilfe für den Entwickler gedacht und nicht als Fehlermeldung für den Benutzer. Assert - Beispiel #include <iostream> #include <cassert> int main () { int a, b; std::cin >> a >> b; assert (b!=0); // Output: a/b std::cout << a/b << "\n"; return 0; } Tipps zu Serie 4 Aufgabe 1 › Gesucht: Anzahl der Zahlen n zwischen 1 und 1000 mit genau k Teilern, für k beliebig › Wie kann man a teilt b in C++ ausdrücken? › For loop: Siehe Primzahlbeispiel › Teiler zählen pro Zahl. Aufgabe 2 › Theorieaufgabe Papier › Ihr müsst keinen Code schreiben, dürft aber. › Verschieden Lösungen möglich, gut begründen (auch wenn ihr Code geschrieben habt)! › Diese Aufgabe kann euch in zukünftigen Serien/an der Prüfung oder in echten Programmen helfen… Aufgabe 3 › Gesucht: Approximation für pi › Arbeitet mit double › In welche Richtung soll addiert werden? › Schaut euch das Beispiel zu harmonischen Zahlen im Skript an! Aufgabe 4 › Szenario: Jedes Jahr werden m Franken auf ein Konto bezahlt (1. Januar). Jedes Jahr gibt es auf den Kontostand p % Zins (31. Dezember). Wie viel Geld ist nach n Jahren da? › Schreibt euch die Rechnung erst auf und formt allenfalls etwas um. › Welcher Loop passt hier? › Einlesen mehrerer Variablen klar? Weiter geht’s! Bald geht’s weiter… Pause! bis 16:18