Vorlesung3. Sitzung Grundlegende Programmiertechniken Wintersemester 2007/2008 Dozent Nino Simunic M.A. Computerlinguistik, Campus DU Grundlegende Programmiertechniken, WS 2007/2008 Ausdrücke, Operatoren Kontrollfluss steuern via Verzweigung Ausdrücke: Einleitung Allgemein: Elementarsten (ausführbaren) Programmeinheiten, welche einen Wert haben/zurückgeben: Literale, Numerale, Variablen Komplexe/Zusammengesetzte Ausdrücke bestehen aus Klammern, Operanden und Operatoren beschreiben bspw. eine Berechnungsvorschrift -3- Einschub: Literale/Numerale in Java Einschub: Literale/Numerale in Java Explizite Repräsentation von Werten primitiven Typs und Zeichenketten (Strings) im Quelltext: Boolesche Literale Zeichen Literale null Zeichenketten (String-)Literale -4- 12, 45, 823462346 Null Literal 1.5, 124.1255 Integer/Ganzzahl Literale (Numerale) '€', '\u20ac', … Fließkomma Literale (Numerale) true oder false "Hello, Dave" Ausdrücke: Zusammengesetzte, Anweisung Ausdrücke: Zusammengesetzte, Anweisung Zusammengesetzer Ausdruck: Kombination aus Operator(-en) und Operand(-en) Dienen bspw. dazu, Variablen einen Wert zuzuweisen (a = 12) numerische Berechnungen durchzuführen (12 + 4) logische Bedingungen zu formulieren ( x>2 || y<4 ) Ein auf ein Semikolon endender Ausdruck ist eine Anweisung. -5- double spdProzent = prozentWert * grundWert / 100; Ausdrücke: Operanden Ausdrücke: Operanden Operanden in Ausdrücken Sind die bereits vorgestellten Literale oder Variablen. Zum Beispiel: double d = 5 * 10 / y ; String date = "18.11." + yearVar; Methoden- bzw. Konstruktorenaufrufe Integer.parseInt(args[0])*Math.random()*3.5 Hinweis: In Java existieren keine Funktionen, sondern Methoden. In beiden Fällen: Sie können Werte zurückgeben! Mehr zum Konzept »Methoden« später. -6- Ausdrücke: Typ, Rückgabewert Ausdrücke: Typ, Rückgabewert Jeder Ausdruck hat einen Rückgabewert bestimmten Typs. Der Typ des Rückgabewerts bestimmt sich aus den Typen der Operanden und der Art des verwendeten Operators. Zum Beispiel: -7- a > b ( Relationaler Operator, Typ: boolean ) 2 + 5 ( Arithmetisch. Op.,Typ: int, short, long, …) Operatoren: Allgemeine Unterscheidungsebenen Operatoren: Allgemeine Unterscheidungsebenen Operator(-typ) -8- Arithmetischer Operatoren, Logische O., … Stelligkeit Stellung Präzedenz Assoziativität Stelligkeit Operatoren: Stelligkeit Die Stelligkeit des Operators bestimmt die Anzahl obligatorischer Operanden -9- unär: ein Operand (bspw. bei der Negation (-a); binär : zwei Operanden (bspw. Addition: a + b) ternär : drei Operanden (bspw. a ? b : c) Stellung Operatoren: Stellung Allgemeine Unterscheidung nach Stellungskriterien: Infix, Präfix, Postfix Infix Präfix Vor dem Operanden. ++a Postfix -1010- Zwischen den Operanden. Bspw. Addition: a + b Nach dem Operanden. a++ Präzedenz (a) Operatoren (a): Präzedenz Präzedenz ((Vor-)Rang, Priorität) eines Operators bestimmt die Reihenfolge der Ausführung der Operationen, wenn ein Ausdruck mehrere Operatoren enthält. -1111- Operationen mit höherer Priorität werden vor Operationen mit niedriger Priorität ausgeführt. Durch Klammerung kann diese Ausführungsreihenfolge modifiziert werden. Bei Operanden gleicher Priorität muss die Assoziativität der Operatoren beachtet werden. Präzedenz (Beispiele) Operatoren (b): Präzedenz Multiplikation vor Addition (Punkt vor Strich) a - b * c / d Enstprechung: (a –b ) * c / d Enstprechung: ( a - ( ( b *c ) / d )) ( ( (a - b) * c ) / d ) Änderung der Priorität via Klammerung Präzedenz bei Zuweisung und Berechnung: Zuweisungsoperatoren haben eine niedrigere Präzedenz als arithmetische Operatoren: a = a + 1 Zuerst wird rechts a + 1 ausgewertet, dann der Ergebniswert zugewiesen. -1212- Assoziativität Ausdrücke: Assoziativität Assoziativität beschreibt die Auswertungsreihenfolge von Operatoren derselben Bindungskraft. Zwei Ausprägungen: Links-Assoziativität Z.B. sind Summationsoperatoren sind linksassoziativ: Auswertung von und nicht als als (a-b)+c Rechts-Assoziativität Bspw. Zuweisungsoperatoren sind rechtsassoziativ: Auswertung von -1313- a-b+c a-(b+c) b = a = 1 wie Operationstypen b = ( a = 1 ) Operatoren: Typen Arithmetische Operatoren Bit-Operatoren Bspw. '=' oder '+=' Sonstige -1414- Bspw. '&&' oder '||' Zuweisungsoperatoren Bspw. '>' oder '<' Logische Operatoren Bspw. >> oder & Vergleichsoperatoren Bspw. + oder - Bspw. Konkatenations-Plus, (ZIELTYP) oder ? : Arithmetische, Vorzeichen Op. Operatoren: Arithmetische O., Vorzeichen O. (1) Allgemein: Arithmetische Operatoren verrechnen ein oder zwei Werte zu einem neuen Wert Insgesamt fünf arithmetische Operatoren und zwei Vorzeichen-Operatoren: Binäre additive Operatoren: + Addition (Priorität 5/15, linksassoziativ) - Subtraktion (Priorität 5/15, linksassoziativ) Binäre multiplikative Operatoren: * Multiplikation (Priorität 4/15, linksassoziativ) / Division (Priorität 4/15, linksassoziativ) % Modulus (Rest-Operator) (Priorität 4/15, linksassoziativ) Vorzeichen + Identität - Negation -1515- (unäres Plus) (Priorität 2/15, linksassoziativ) (unäres Minus) (Priorität 2/15, linksassoziativ) ArithmeticOps.java ArithmeticOps.java class ArithmeticOps { public static void main(String[] args) { int a = 4; int b = 2; System.out.println(a + b); System.out.println(a - b); System.out.println(a * b); System.out.println(a / b); System.out.println(a % b); System.out.println(a * -b); System.out.println(-a * -b); } } -1616- Operatoren: Typ eines Ausdrucks (1) Operatoren: Typ eines Ausdrucks (1) Jeder Ausdruck hat einen Typ Zwei Möglichkeiten: Ausdruck-Elemente sind gleichen Typs Dann ist der Typ des Ausdrucks identisch mit dem Typen seiner Elemente. Ausdruck-Elemente sind unterschiedlichen Typs Dann hat der Ausdruck den Typ des genaueren/umfassendsten Typs im Ausdruck double (1.2) ist umfassender/genauer als int (1) -1717- Operatoren: Typ eines Ausdrucks (2) Operatoren: Typ eines Ausdrucks (2) Operanden eines Ausdrucks müssen kompatibel sein int x; x = 2.5; Kompilierungsfehler: Datentypen sind nicht kompatibel Zwei Typen sind kompatibel, wenn -1818- sie identisch sind, oder wenn sie durch implizite Typanpassung/konvertierung zum gleichen Typ führen Typkompatibilität Typkompatibilität, Cast-Operator Implizite (automatische) Typkonvertierung byte→short→int→long→float→double(→ String) Z.B. von short nach long ok, von long nach short ungültig. Explizite Typanpassung via Cast-Operator Syntax: (TYPE) expression Beispiel: int x; x = (int) 2.5; Kann zu Datenverlust und Ungenauigkeit führen! x ist jetzt 2 -1919- Beispiele, Typkompatibilität »Arithmetische« Ausdruckstypen, Typkompatibilität (1) int i1=4, i2=2, i3=5; double d1 = 3, d2 = 2; System.out.println(i1 = i1 + i2 ); // i1=? // 6 /* i1 hat Typ int, i2 hat Typ int, also hat der Ausdruck den Typ int */ System.out.println(d1 = d2 + i2 ); // d1=? // 4.0 /*d2 hat Typ double,i2 hat Typ int -> Ausdruck hat den genaueren Typ * double */ -2020- Bsp.: (Un-)Genauigkeiten »Arithmetische« Ausdruckstypen, Typkompatibilität (2) System.out.println( i1 = i3 / i2 ); // i1 jetzt 2 /* i1 hat Typ int, i2 hat Typ int, also hat auch der Ausdruck den Typ int. In solchen Fällen wird immer gen .0 gerundet */ System.out.println( d1 = i3 / i2 ); //2.0 /* a) Beide Op. Typ int, Ausdruck Typ int -> Wert ist 2 (Rundung zu .0) * b) Zuweisung von int zu double, implizit: d1 daher 2.0 */ System.out.println( d1 = i3 / d2 ); // 2.5 /* Rechter Ausdruck vom genaueren Typ double. * Berechnung genauso genau: 2.5 (keine Rundung!)*/ -2121- Bsp.: cast »Arithmetische« Ausdruckstypen, Typkompatibilität (3) System.out.println( d1 = (double) (i3 / i2) ); //d1=? //2.0 /* a) Typecast zwecklos, da rechter Ausdruck wg. Klammerung höchste Priorität hat. * Wird erst zu 2.0 ausgewertet, dann zu double gecastet (noch immer 2.0), dann 2.0 * der double-Var. zugewiesen. */ System.out.println( d1 = (double) i3 / i2 ); //d1=? //2.5 // a) Cast (Op.) jetzt höchste Prioriät im Ausdruck. i3 wird zu kompatiblem double. // b) Ganzer Ausdruck wird wg. i3 zu double. // c) Berechnung auf double-Ebene (ohne Rundung!): 2.5 System.out.println( d1 = i3 / (double) i2 ); //d1=? //2.5 // Analog zu Bsp. oberhalb: Diesmal i2 statt i1 -2222- Operatoren: Logische Operatoren (1) Operatoren: Logische Operatoren (1) Verrechnung von ein oder zwei Wahrheitswerten zu einem neuen Wahrheitswert 6 logische Operatoren (a,b: Typ boolean) Logisches/Bitwise Und: a & b (Priorität 9/15, linksa.) Logisches/Bitwise Oder: a | b (Priorität 11, linksa.) Logisches Nicht: ! b (Priorität 2, linksa.) Logisches/Bitwise XOR: a ^ b (Priorität 10, linksa.) … & -2323- falsch wahr falsch f f wahr f w | falsch wahr falsch f w wahr w w Operatoren: Logische Operatoren (2) ^ falsch wahr falsch f w wahr w f Operatoren: Logische Operatoren (2) … Logisches UND mit Short-Circuit-Evaluation (Prio. 12, la.): a && b Ist a bereits falsch, so wird false zurückgegeben und b nicht mehr ausgewertet. Anders bei & (Auswertung stets beider Teile) Logisches ODER mit Short-Circuit-Evaluation (Prio. 13, la.): a || b Ist bereits a wahr, so wird true zurückgegeben und b nicht mehr ausgewertet. Anders bei | (Auswertung beider Teile, egal ob a bereits wahr ist) Unvollständige Auswertung, analog zu: -2424- if (a) { if (b) { … Logik/Bool'-Operatoren: BoolOps.java Logik/Bool'-Operatoren: BoolOps.java public class BoolOps { public static void main(String[] args) { boolean a = true; boolean b = false; System.out.println( a & b ); // false System.out.println( a | b ); // true System.out.println( a ^ b ); // true System.out.println( ! b ); // true // wenn a false ist, Auswertung beendet (ignoriere b): System.out.println( a && b ); // false // wenn a true ist, ignoriere den zweiten Operanden b: System.out.println( a || b ); // true } } -2525- Operatoren: Zuweisungsoperatoren Operatoren: Zuweisungsoperatoren Zuweisungsoperatoren weisen einen Wert zu und liefern den Wert dann als Ergebnis an aufrufender Stelle Insgesamt 12 Operatoren, Priorität 15 (/15, also schwächste) -2626- Sie sind die einzigen Operatoren »Seiteneffekt« =, +=,-=,*=,/=,%=,&=,^=,|=,, <<=, >>=, >>>= Bei den Operatoren +=, %=, … handelt es sich um Kurzformen für eine Berechnung mit folgender Zuweisung. Operatoren: Zuweisungsoperatoren Beispiele: Zuweisungsoperatoren int a = 4; int b = 2; System.out.println(a = b); // 2 System.out.println(b = 5); // 5 System.out.println(a += b); // 7 (analog zu a = a + b) System.out.println(a += a = b);} // Erst a = b (a=5), dann a + b, dann das »alte« a (7) + »neues« a (5), // ergibt 12, dann letzte Zuweisung (a = 12) -2727- Operatoren: Pre-Inkrement/Dekrement Operatoren: Pre-Inkrement/Dekrement Pre-Inkrement/Dekrement (++x, ++y) Verändert den Wert der Variablen und liefert diesen (neuen Wert) an aufrufender Stelle als Ergebnis zurück! Priorität 1/15(höchste), linksassoziativ Post-Inkrement/Dekrement (x++, y++) Verändert den Wert der Variablen, liefert aber an ausführender Stelle den alten Wert als Ergebnis zurück! Priorität 2/15(zweithöchste), rechtsassoziativ Inkrement hat höhere Präzedenz (Prio. 1) als Konkatenationsoperator ( Prio. 5) int a=5; //Seiteneffekt: a)Zuweisung per se (b jetzt 5), // b)gesamter Ausdruck gibt den Wert 5 zurück: int b=a; System.out.println( "(Post-inkr.) a an ausführender Stelle: " + a++); 5 System.out.println( "a danach: " + a); 6 System.out.println( "(Pre-inkr.) b an ausführender Stelle: " + ++b); 6 System.out.println( "b danach: " + b); 6 -2828- Operatoren: Vergleichsoperatoren Vergleichsoperatoren Vergleichsoperatoren liefern immer einen Wahrheitswert (boolean) zurück. Vergleich (Priorität 7/15, linksassoziativ): < <= > >= kleiner als kleiner gleich größer als größer gleich Äquivalenz (Priorität 8/15, linksassoziativ): -2929- Beide Operanden müssen einen kompatiblen Typ haben == != gleich ungleich Vergleichsoperatoren, Quelltext : CompOps.java Vergleichsoperatoren, Quelltext : CompOps.java class CompOps { public static void main(String[] args) { int a = 5; Vorsicht Falle! = ist Zuweisung, == ist Vergleich. Immer. Überall. int b = 3; System.out.println( a == b ); // false System.out.println( a != b ); // true System.out.println( a > b ); // true System.out.println( a < b ); // false System.out.println( a >= b ); // true System.out.println( a <= b ); // false } } -3030- Operatoren: Bitwise Operatoren: Bitwise Operator -3131- Name Beispiel a & b and 3 & 5 1 1, wenn beide Bits 1 sind. a | b or 3 | 5 7 1, wenn eines der Bits 1 ist. a ^ b xor 3 ^ 5 6 1, wenn beide Bits unterschiedlich sind. ~a not ~3 -4 Invertiert die Bits. n << p left shift 3 <<< 2 12 Shift des Bits von n links um p Positionen. 0-Bits werden in loworder Positionen geshiftet. n >> p right shift 5 >> 2 1 Shift des Bits von n rechts um p Positionen. n >>> p right shift 15 Shift des Bits von n rechts um p Positionen. Nullen werden zu high-order Positionen geshiftet. -4 >>> 28 Ergebnis Description Illustration (1): Präzedenz und Assoziativität Illustration (1): Präzedenz und Assoziativität double z,p,r,q,w,y,x; z = p = r = q = w = y = x = 0.0; //... -3232- Illustration (2): Präzedenz und Assoziativität Illustration (2): Präzedenz und Assozation -3333- If-else Grundlegende Programmiertechniken, WS 2007/2008 Kontrollfluss steuern (Verzweigung) Entscheidungen fällen Bisher: Was ist, wenn Entscheidungen getroffen werden sollen? Anweisungen wiederholt werden sollen? Notwendigkeit: Kontrollfluss steuern -3535- Anweisungsabfolge linear Nur ein Pfad durch die Anweisungen Jede Anweisung wird genau einmal ausgeführt Umsetzung: Verzweigende Anweisung (via if-else) If-else: Allgemeine Form If-else: Allgemeine Form -3636- Bedingungen Bedingungen -3737- IfElseTest.java If-Else im Quelltext: IfElseTest.java class IfElseTest { public static void main(String[] args) { int eingabe = -14; if (eingabe<0) {//fuehre erste Anweisung aus, falls Bedingung true System.out.println(-eingabe); } else { // fuehre zweite Anweisung aus, falls Bedingung false System.out.println(eingabe); } // Bei einfachen Konstrukten auch Formatierung anstatt Klammerung: if (eingabe<0) System.out.println(-eingabe); else // fuehre zweite Anweisung aus, falls Bedingung false System.out.println(eingabe); } } -3838- (Einschub) Sonstige Operatoren: Tern-Operator (Einschub) Sonstige Operatoren: Tern-Operator (TernOp.java) class TernOp { public static void main(String[] args) { int eingabe = -5; int zahl = (eingabe < 0) ? -eingabe : eingabe ; System.out.println(zahl);// 5 eingabe = 7; System.out.println((eingabe < 0) ? -eingabe : eingabe); } } -3939- Ende Nächste Woche Objektorientierte Programmierung, Teil 1 Klassen, Objekte, Konstruktoren, Methoden ----------------Tutorien: Personen, die sich fürs Tutorium interessieren, schicken mir bitte bis kommenden Montag eine Mail mit Wunschzeiten (zwei sollten es schon sein). -4040-