Informatik I Tutorium WS 07/08 Vorlesung: Prof. Dr. F. Bellosa Übungsleitung: Dipl.-Inform. A. Merkel Tutorium: 12 Tutor: Jens Kehne Tutorium 5: Dienstag 26. November 2007 Agenda des heutigen Tutoriums http://info1.informatik.uni-karlsruhe.de Übersicht heute • Rückblick • Theorie • Lebensdauer und Sichtbarkeit • Java • Bedingte Sprünge, Schleifen 2 Rückblick http://info1.informatik.uni-karlsruhe.de • EBNF: Nichtterminale definieren! • Die Lösung muss für sich genommen verständlich sein! • Aufgabenstellungen genau lesen! • Wenn eine Begründung verlangt ist, solltet ihr auch eine hinschreiben. • Geschenkte Punkte :-) http://info1.informatik.uni-karlsruhe.de Theorie Lebensdauer und Sichtbarkeit von Variablen Wann sind Variablen sichtbar? http://info1.informatik.uni-karlsruhe.de • Wie bestimmt man die Sichtbarkeit von Variablen? class FirstOutProgram { public int min; static int computeMax(int a, int b){ if (a>b) return a else return b; } public static void main (String[] arg) { int v, max; … if (max < v){ int min = v; } } } Wann leben Variablen http://info1.informatik.uni-karlsruhe.de • Was sind lokale und globale Variablen? Was heißt „überschreiben“ einer Variablen? • Wo leben lokale Variablen? • Im gesamten Abschnitt, in welchem sie deklariert werden • Wo sind lokale Variablen sichtbar? • Ab dem Punkt der Deklaration bis zum Abschnittsende • Wo leben globale Variablen? • In der ganzen Klasse • Wo sind globale Variablen sichtbar? • In der ganzen Klasse, außer sie wurden überschrieben Aufgabe 1: Lebensdauer und Sichtbarkeit http://info1.informatik.uni-karlsruhe.de Geben Sie an, welche Variablen an den mit /* 1 */, /* 2 */ und /* 3 */ gekennzeichneten Stellen im folgenden Programm leben und welche davon sichtbar sind. Begründen Sie Ihre Antwort. Verwenden Sie für die Begründung der Sichtbarkeit die aus der Vorlesung bekannte Darstellung. a) Hinweis zur Aufgabe b) Wann leben Variablen? c) Wann sind Variablen sichtbar? Hinweis: Die Variable arg[] der Methode main() soll bei dieser Betrachtung nicht berücksichtigt werden. Aufgabe 1: Lebensdauer und Sichtbarkeit http://info1.informatik.uni-karlsruhe.de class Program{ static int offset = 3; public static void main (String[] arg){ int offset = In.readInt(); int in1 = In.readInt(); int in2 = In.readInt(); Out.println(foobar(offset,in1,in2)); } public static int foobar(int add, int a,int int min = calcMin(a,b); min = doSomething(min) + add; return min; } public static int doSomething(int some){ int lala = some + offset; return lala; } } // end class Program /* 1 */ b){ /* 2 */ /* 3 */ Lösung: Sichtbarkeit http://info1.informatik.uni-karlsruhe.de Lösung: Die Sichtbarkeit der Variablen lässt sich mit folgender Abbildung begründen: class Program{ static int offset = 3; public static void main (String[] arg){ int offset = In.readInt();/* 1 */ int in1 = In.readInt(); int in2 = In.readInt(); Out.println(foobar(offset,in1,in2)); } public static int foobar(int add, int a,int b){ int min = calcMin(a,b); /* 2 */ min = doSomething(min) + add; return min; } public static int doSomething(int some){ int lala = some + offset; /* 3 */ return lala; } } // end class Program offset (global) offset Sichtbar: offset (lokal) a, b, add min Sichtbar: a, b, add, offset (global) some lala Sichtbar: lala, some, offset (global) es sind sichtbar Stelle 1 offset (lokal) Stelle 2 a, b, add, offset (global) Stelle 3 lala, some, offset (global) Lösung Lebendigkeit class Program{ static int offset = 3; public static void main (String[] arg){ int offset = In.readInt();/* 1 */ int in1 = In.readInt(); int in2 = In.readInt(); Out.println(foobar(offset,a,b)); http://info1.informatik.uni-karlsruhe.de offset offset (global) (lokal) in1, a,b, some, in2 min, lala static int foobar(int add, int a,int b) int min = calcMin(a,b); /* 2 */ min = doSome(min) + add; int doSome(int some){ int lala = some + offset;/* 3 */ return lala; } return min; } } } // end class Program Lösung: Lebendigkeit von Variablen http://info1.informatik.uni-karlsruhe.de Lösung: Die Lebendigkeit der Variablen lässt sich wie folgt begründen: Stelle 1 Stelle 2 Stelle 3 es leben offset (global), offset (lokal), in1, in2 Stelle 1, a, b, add, min Stelle 2, some, lala es sind sichtbar offset (lokal) a, b, add, offset (global) lala, some, offset (global) An Stelle 1 leben nur die in der main()-Methode definierte lokale Variable offset sowie die globale Variable offset und die in der Methode deklarierten: in1, in2. Da die Methode foobar() von der Methode main() aufgerufen wird, leben an Stelle 2 neben den in der Methode selbst definierten Variablen a, b, min auch die in der Methode main() lebenden Variablen. Da die Methode doSomething() von der Methode foobar() aufgerufen wird, leben an Stelle 3 neben den in der Methode selbst definierten Variablen some und lala auch die in der Methode foobar() lebenden Variablen. http://info1.informatik.uni-karlsruhe.de Praxis Schleifentransformation & Schleifenvergleich 12 for-Anweisung http://info1.informatik.uni-karlsruhe.de Syntax • "for" "(" Initialisierungsteil";" Abbruchbedingung";" Inkrementierungsteil ")" Schleifenrumpf ";" Beispiel • for (int i = 0; i<100; i++) Out.print("*"); In welcher Reihenfolge werden die Teile ausgeführt? 1. Initialisierung 2. Prüfe Abbruchbedingung 3. Führe Schleifenrumpf aus 4. Führe Inkrementierungsteil aus und gehe zu 2. 13 while- und do-while-Anweisung http://info1.informatik.uni-karlsruhe.de • Durch die while-Anweisung wird eine Abweisschleife realisiert • Die do-while-Anweisung realisiert eine Durchlaufschleife int •n = In.readInt(); Beispiel: if (n < 0) n = -n; // no negative values while (n > 0) { Out.print(n % 10); // rest from n / 10 n = n / 10; } int n = In.readInt(); if (n < 0) n = -n; do { Out.print(n % 10); n = n / 10; } while (n > 0); // no negative values // rest from n / 10 Was ist der Unterschied zwischen den beiden Programmen? Die rechte Schleife läuft mindestens 1 mal durch, die linke nur in Abhängigkeit von n! 14 Die Anweisung break http://info1.informatik.uni-karlsruhe.de int x = In.readInt(); int y = In.readInt(); while (y > 0) { while (x > 0) { if (x > 5) { if (x == 7) break; } Out.print("1"); x--; } Out.print("2"); y--; } Out.print("3"); • Der Befehlt break realisiert den Abbruch innerhalb eines Rumpfes • einer switch-Anweisung • einer while-Schleife • einer for-Schleife • etc. • Warum sollte man break sparsam verwenden? Was gibt das Programm auf dieser Folie aus bei Eingabe von 11223 • x == 2 und y == 2 2223 • x == 7 und y == 3 1123 • x == 9 und y == 1 • 15 Aufgabe 2: Schleifentransformation http://info1.informatik.uni-karlsruhe.de Wandeln Sie folgende for-Schleife in eine while-Schleife und in eine do-while-Schleife um. Verwenden Sie in den Schleifen keine break-Anweisung. int s = 0; for (;;) { int x = ln.readInt(); if (x<0) break; s = s + x; } Lösung Schleifentransformation: Als while-Schleife: Als do-while-Schleife: int s = 0; int s = 0; int x = In.readInt(); do { int x = In.readInt(); while (x >= 0) { if (x >= 0) s = s + x; s = s + x; x = In.readInt(); } } while (x >= 0); 16 Aufgabe 1a: Schleifenvergleich http://info1.informatik.uni-karlsruhe.de Schreiben Sie für die folgenden Aufgaben jeweils ein Programm, das den am besten geeigneten Schleifentyp (while-, for- oder do-while-Schleife) verwendet. Begründen Sie Ihre Auswahl. a) Zuerst wird ein positiver ganzzahliger Wert eingelesen. Es werden anschließend genau so viele Zahlen eingelesen, wie der anfangs eingelesene Wert angibt und nach Eingabe jeder Zahl wird die Summe der bis dahin gelesenen Zahlen ausgegeben. 17 Aufgabe 1a: Schleifenvergleich http://info1.informatik.uni-karlsruhe.de Lösung a): for - Schleife verwenden, da die Anzahl der Iterationen vorab bekannt ist public class SumWithForLoop { public static void main(String[]args) { int sum = 0; int count; Out.print("Es werden entsprechend der vorgegebenen Anzahl Zahlen summiert\n"); Out.print("Anzahl der summierenden Zahlen eingeben: "); // enter number of inputs int num = In.readInt(); if(num>0) { // if number not zero for(count = 1; count<=num; count++) { // sum all inputs Out.print("Bitte Summand Nr."+count+" eingeben: "); sum += In.readInt(); // read number from keyboard and calculate new sum Out.println("Summe der bisher eingegebenen Zahlen: "+sum); } } } } 18 Aufgabe 1b: Schleifenvergleich http://info1.informatik.uni-karlsruhe.de Schreiben Sie für die folgenden Aufgaben jeweils ein Programm, das den am besten geeigneten Schleifentyp (while-, for- oder do-while-Schleife) verwendet. Begründen Sie Ihre Auswahl. b) Bis zur Eingabe einer 0 sind ganze Zahlen einzulesen. Sofern es sich bei der Eingabe um keine 0 handelt, wird nach Eingabe die Summe der bisher gelesenen Zahlen ausgegeben. 19 Aufgabe 1b: Schleifenvergleich http://info1.informatik.uni-karlsruhe.de Lösung b): while - Schleife wird verwendet, da die Prüfung der Abbruchbedingung (Eingabe ist 0) bereits vor der ersten Summation und Ausgabe erfolgen muss. public class SumWithWhileLoop { public static void main(String[]args) { int sum = 0; int count = 1; int num; Out.print("Die eingegebenen Zahlen werden bis zur Eingabe von '0' summiert\n"); Out.print("Bitte Summand Nr."+count+" eingeben: "); num = In.readInt(); // read number from keyboard while(num!=0) { // while number not zero sum += num; // calculate new sum Out.println("Summe der bisher eingegebenen Zahlen: "+sum); // print new sum count++; Out.print("Bitte Summand Nr."+count+" eingeben: "); num = In.readInt(); } } } // read next number from keyboard 20 Aufgabe 1c: Schleifenvergleich http://info1.informatik.uni-karlsruhe.de Schreiben Sie für die folgenden Aufgaben jeweils ein Programm, das den am besten geeigneten Schleifentyp (while-, for- oder do-while-Schleife) verwendet. Begründen Sie Ihre Auswahl. c) Zunächst ist ein positiver ganzzahliger Grenzwert einzulesen. Danach werden ganze Zahlen eingelesen und nach Eingabe jeder Zahl wird die Summe der bisher gelesenen Zahlen ausgegeben, bis die Summe (inklusive der zuletzt eingegebenen Zahl) den Grenzwert überschritten hat. 21 Aufgabe 1c: Schleifenvergleich http://info1.informatik.uni-karlsruhe.de Lösung c): do while - Schleife, da die Prüfung der Abbruchbedingung erst nach der Eingabe des ersten Summanden und Ausgabe der Summe erfolgt. public class SumWithDoWhileLoop { public static void main(String[]args) { int sum = 0; int count = 0; int num; int max; Out.print("Es werden Zahlen werden bis zum eingegebenen Grenzwert summiert\n"); Out.print("Bitte Grenzwert eingeben: "); max = In.readInt(); // read number from keyboard do { // do while sum <= max count++; Out.print("Bitte Summand Nr."+count+" eingeben: "); num = In.readInt(); // do while sum <= max sum += num; // calculate new sum Out.println("Summe der bisher eingegebenen Zahlen: "+sum); // print new sum } while(sum<=max); }} 22 Beispiel Switch http://info1.informatik.uni-karlsruhe.de int x = In.readInt(); switch (x) { case 1: ... break; case 2: case 3: ... break; default: ... } Falls x == 1 ... Break terminiert den case-Block Leerer Block (ohne break wird der folgende Block mit ausgeführt) Wenn keine der Möglichkeiten passt... Sonstiges http://info1.informatik.uni-karlsruhe.de • Einzelne Buchstaben lassen sich wie Zahlen vergleichen • Es gilt: 0 < … < 9 < … < A < … < Z < … < a < … < z • Es werden einfach die ASCII-Codes verglichen. • Den Unicode-Wert eines Zeichens erhält man, indem man das Zeichen nach int castet. • int i = (int) c; • Grundsätzlich alles kommentieren. http://info1.informatik.uni-karlsruhe.de Fragen? Fragen? Fragen? Fragen? Fragen? uestions? Questions? Fragen? Fragen? Fragen? Fragen? Fragen? Questions? Fragen? Questions? Questions? Fragen? Questions? Questions? Questions? Questions? Questions? Fragen? Ques Questions? Questions? Questions? Bis bald … http://info1.informatik.uni-karlsruhe.de Credits http://info1.informatik.uni-karlsruhe.de • Erstellung und Zusammenstellung des Materials: • Christian Maier (Zusammenstellung) • Stephan Kessler (Überarbeitung und Erweiterung)