Programmierung WS11/12 Lösung - Übung 1 Prof.aa Dr. J. Giesl M. Brockschmidt, F. Emmes, C. Fuhs, C. Otto, T. Ströder Tutoraufgabe 1 (Syntax und Semantik): 1. Was ist Syntax? Was ist Semantik? Erläutern Sie den Unterschied. 2. Impliziert gleiche Syntax auch gleiche Semantik? Geben Sie ein Beispiel. 3. Erläutern Sie folgende Aussage: Ein syntaktisch korrektes Programm ist nicht immer korrekt. Lösung: . Tutoraufgabe 2 (Formale Sprachen und Grammatiken): Gegeben sei die folgende Sprache: L = {w ∈ {a, b}∗ | Hierbei bezeichnet mit a Es existiert ein y ∈ {a, b}∗ w = ay mit oder ]b (w ) = 2} ]b (w ) die Anzahl der b-s in dem Wort w . Das heiÿt, L enthält genau die endlichen Wörter, die b-s enthalten. beginnen oder genau zwei Die folgenden Wörter sind beispielsweise in der Sprache enthalten: bab ababba abba Folgende Wörter sind nicht Bestandteil der Sprache: baa babaab b a) Geben Sie eine kontextfreie Grammatik an, welche die Sprache b) Geben Sie eine Grammatik in EBNF mit nur einer Regel an, die L erzeugt. L deniert. Um die Lesbarkeit zu erhöhen, dürfen Sie Anführungszeichen um Terminalsymbole weglassen. c) Geben Sie ein Syntaxdiagramm ohne Nichtterminalsymbole an, das die Sprache L deniert. Lösung: a) Die kontextfreie Grammatik G = (N, T, P, S) S S A A B B B mit N = {S, A, B}, T = {a, b} −→ −→ −→ −→ −→ −→ −→ 1 AbAbA aB aA ε aB bB ε und P deniert wie folgt: Programmierung WS11/12 Lösung - Übung 1 erzeugt genau die Sprache L. Mit dem Nonterminal S wählt a beginnt. Das Nonterminal A möchte oder eines, das mit Anzahl der b-s man, ob man ein Wort mit zwei erzeugt beliebig viele im Wort konstant. B erzeugt beliebige Wörter aus beliebige Folgen von a und b {a, b}∗ , Konstruktion eines Wortes, das genau zwei b-s erzeugen da nach dem Wortanfang S −→ AbAbA, A enthält. Nutzt man aber das erste a dient eigentlich zur zur Ableitung eines ist das Wort wegen der zweiten Bedingung in der Sprache enthalten und könnte genauso mithilfe der zweiten Regel abgeleitet werden. Es ist daher möglich, die erste Regel durch b) b-s Dadurch bleibt die folgen können. Es ist auch möglich, die Lösung leicht abzuwandeln. Die erste Regel, a, a-s. Die folgende Grammatik in EBNF mit nur einer Regel deniert genau S −→ bAbA zu ersetzen. L. S = ({a}b{a}b{a} | a{(a | b)}) | {z } | {z } 1 2 Diese Konstruktion ist ähnlich zu der Grammatik aus Teilaufgabe a). In der ersten Hälfte wird ein Wort mit genau zwei {a, b}∗ b-s erzeugt. Im zweiten Teil ein Wort, das mit a beginnt und mit einem beliebigen Wort aus endet. Analog zur alternativen Lösung in Teilaufgabe a) kann hier eine Vereinfachung vorgenommen werden: S = (b{a}b{a} | a{(a | b)}) | {z } | {z } 1 c) 2 Das folgende Syntaxdiagramm deniert die Sprache L: a a b a b a a b Auch hier gibt es wie in Teilaufgaben a) und b) eine etwas weniger komplexe Lösung: b a a b a a b . 2 Programmierung WS11/12 Lösung - Übung 1 Aufgabe 3 (Formale Sprachen und Grammatiken): (3 + 3 + 3 = 9 Punkte) Gegeben sei die folgende Sprache: L = {w ∈ {a, b}∗ | Hierbei bezeichnet mit a Es existiert ein y ∈ {a, b}∗ mit w = ay b ]a (w ) die Anzahl der a-s in dem Wort w . Das heiÿt, L b enden oder nur ein bzw. zwei a-s enthalten. oder 1 ≤ ]a (w ) ≤ 2} enthält genau die endlichen Wörter, die beginnen und mit Die folgenden Wörter sind beispielsweise in der Sprache enthalten: bab aaaaab abbbba a Folgende Wörter sind nicht Bestandteil der Sprache: bababa baaaab a) Geben Sie eine kontextfreie Grammatik an, welche die Sprache b) Geben Sie eine Grammatik in EBNF mit nur einer Regel an, die L erzeugt. L deniert. Um die Lesbarkeit zu erhöhen, dürfen Sie Anführungszeichen um Terminalsymbole weglassen. c) Geben Sie ein Syntaxdiagramm ohne Nichtterminalsymbole an, das die Sprache L deniert. Lösung: a) Die kontextfreie Grammatik G = (N, T, P, S) mit −→ −→ −→ −→ −→ −→ −→ −→ S S S X X X B B erzeugt genau die Sprache b Mit dem Nonterminal am Ende, ein Wort mit einem Das Nonterminal der Regeln für von b) L. a und b B B N = {S, B, X}, T = {a, b} a und P deniert wie folgt: aXb BaB BaBaB aX bX ε bB ε S wählt man, ob man ein Wort mit oder ein Wort mit zwei a-s a am Anfang und erzeugen möchte. b-s. Die Anzahl der a-s im Wort ändert sich durch die Verwendung {a, b}∗ , da nach dem Wortanfang a beliebige Folgen mit b endet. erzeugt beliebig viele nicht. X erzeugt beliebige Wörter aus folgen können, bevor es Die folgende Grammatik in EBNF mit nur einer Regel deniert genau L. S = (a{(a | b)}b | {b}a{b}(ε | a{b})) | {z } | {z } 1 2 Diese Konstruktion ist analog zu der Grammatik aus Teilaufgabe a). In Teil mit c) a beginnt und b endet. In Teil (2) (1) wird ein Wort erzeugt, das ein oder zwei Das folgende Syntaxdiagramm deniert die Sprache 3 L: wird ein Wort erzeugt, das a-s enthält. Programmierung WS11/12 Lösung - Übung 1 a a b b b a b a b . Tutoraufgabe 4 (Zweierkomplement): a) Erklären Sie im Detail, wie die beiden Ausgaben des folgenden Programms berechnet werden. public class Test { public static void main ( String [] args ) { int zahl = -2147483648; } } Hinweis: b) System . out . println ( zahl + 1); System . out . println ( zahl - 1); −231 = −2147483648 Welche Zahlen repräsentieren die folgenden Bitfolgen im 5-Bit Zweierkomplement? 00010 c) Sei x 10111 11011 01101 10000 eine ganze Zahl. Wie unterscheidet sich die Zweierkomplement-Darstellung von x und −x ? Lösung: a) Im Folgenden werden Binärzahlen mit einem Z markiert, wenn die Zahl im Zweierkomplement verstanden werden muss. Die Zahl Der Datentyp int 1111Z ist also als −1 zu verstehen, während benutzt 32 Bit. Die Darstellung der Zahl 10000000000000000000000000000000 Z (31 Nullen) 4 1111 −2147483648 für die Zahl 15 steht. im Zweierkomplement ist Programmierung WS11/12 Lösung - Übung 1 Das Ergebnis der Addition zahl + 1 berechnet sich wie folgt: 10000000000000000000000000000000 Z 00000000000000000000000000000001 Z -------------------------------10000000000000000000000000000001 Z Auch hier gibt die führende 1 an, dass die dargestellte Zahl negativ ist. Den Dezimalwert der dargestellten Zahl erhält man durch Invertieren und Addieren von 1 01111111111111111111111111111110 00000000000000000000000000000001 -------------------------------01111111111111111111111111111111 was für 2147483647 steht. Mit der Vorzeicheninformation ergibt sich -2147483647. Berechnet man zahl - 1, berechnet sich das Ergebnis durch die Addition mit -1. Die Zahl -1 ist im Zweierkomplement dargestellt durch 11111111111111111111111111111111 Z Die Addition -2147483648 + (-1) ergibt demzufolge 10000000000000000000000000000000 Z 11111111111111111111111111111111 Z -------------------------------01111111111111111111111111111111 Z Das Ergebnis ist also nicht negativ (angedeutet durch die führende 0) und entspricht der Dezimalzahl +2147483647. Dieses Ergebnis wird auch durch das Java-Programm ausgegeben. b) Bitfolge c) 5-Bit Zweierkomplement 00010 2 10111 -9 11011 -5 01101 13 10000 -16 Ausgehend von der Zweierkomplement-Darstellung von die Zweierkomplement-Darstellung von a) vertausche alle b) addiere 0 und x erreicht man durch die folgenden beiden Schritte −x . 1en 1 −x Mit diesen beiden Schritten ist es auch die Rückrichtung ( zu x) möglich. In der folgenden Tabelle nden Sie alle Binärzahlen mit drei Ziern. Man erkennt, dass das genannte Verfahren funktioniert. 3 011 2 010 1 001 0 000 -1 111 -2 110 -3 101 -4 100 . 5 Programmierung WS11/12 Lösung - Übung 1 Aufgabe 5 (Zweierkomplement): a) Welche Zahlen repräsentieren die folgenden Bitfolgen im 10-Bit Zweierkomplement? 0000000000 b) (2,5 + 3,5 = 6 Punkte) 1111111111 0000111101 Die zwei folgenden Java-Ausdrücke werten jeweils zu true 1000111101 1011100110 aus, obwohl dies auf den ersten Blick nicht oensichtlich erscheint. Geben Sie dafür jeweils eine kurze informelle Begründung. 1) 0 > 2 000 000 000 + 300 000 000 2) −(−2147483648) + 2147483647 == −1 Hinweis: Der Operator == vergleicht zwei Zahlen auf Gleichheit. Lösung: a) Bitfolge b) 1) Die Berechnung von 10-Bit Zweierkomplement 0000000000 0 1111111111 -1 0000111101 61 1000111101 -451 1011100110 -282 2 000 000 000 + 300 000 000 Das eigentlich erwartete Ergebnis 2 300 000 000 hat als Ergebnis −1994967296. lässt sich im Datentyp int nicht mehr darstellen, und es kommt zu einem Überlauf. 2) Bei der Berechnung von (was 01 . . . 1 −(−2147483648) wird der entsprechende Bitvektor 10 . . . 0 zunächst invertiert 1 auf diesen Bitvektor addiert (was den Bitvektor 10 . . . 0 ergibt). ergibt), und dann noch Der entstandene Bitvektor ist genau derselbe, von dem wir ursprünglich ausgegangen sind. Wir berechnen also eigentlich −2147483648 + 2147483647, was tatsächlich −1 ergibt. . Tutoraufgabe 6 (Einfache Programmierung): a) Schreiben Sie ein einfaches Java Programm, welches den Benutzer auordert, ein Wort einzugeben. Danach soll das Programm ein durch die Return-Taste beendetes Wort einlesen und dieses zweimal hintereinander in einer Zeile ausgeben. Sie dürfen in dieser Teilaufgabe nicht die Methode ( b) System.out.println() System.out.print() verwenden ist hingegen erlaubt). Schreiben Sie ein einfaches Java Programm, welches den Benutzer auordert, zwei Zahlen einzugeben. Diese sollen anschlieÿend (jeweils durch die Return-Taste beendet) eingelesen werden. Danach soll das Programm ausgeben, ob die erste Zahl gröÿer als die zweite, gleich groÿ oder kleiner als die zweite Zahl ist. 6 Programmierung WS11/12 Lösung - Übung 1 Lösung: a) public class Doppelecho { public static void main ( String [] args ) { System . out . println ( " Bitte geben Sie ein Wort ein : " ); String wort = System . console (). readLine (); System . out . println ( wort + wort ); } } b) public class Vergleich { public static void main ( String [] args ) { System . out . println ( " Bitte geben Sie zwei Zahlen ein : " ); int i = Integer . parseInt ( System . console (). readLine ()); int j = Integer . parseInt ( System . console (). readLine ()); System . out . print ( " Die erste Zahl ist " ); System . out . print ( i < j ? " kleiner als " : ( i == j ? " genauso gross wie " : " groesser als " )); System . out . println ( " die zweite Zahl . " ); } } . Aufgabe 7 (Einfache Programmierung): (5 Punkte) Schreiben Sie ein einfaches Java Programm, welches den Benutzer um die Eingabe einer Zahl bittet, diese einliest (die Eingabe soll durch die Return-Taste beendet werden) und ihm anschlieÿend mitteilt, ob die Zahl gerade oder ungerade ist. Danach soll das Programm den Benutzer fragen, wie das Quadrat der zuerst eingebenen Zahl lautet, die Antwort des Benutzers einlesen und schlieÿlich ausgeben, ob der Benutzer korrekt geantwortet hat. Hat er das nicht, soll zusätzlich das richtige Ergebnis ausgegeben werden. Zum Beispiel soll das Programm bei Eingabe der Zahl 4 dem Benutzer mitteilen, dass die Zahl gerade ist. Gibt der Benutzer danach die Zahl 15 ein, so soll das Programm ihm mitteilen, dass die Antwort falsch und die richtige Antwort 16 ist. Hinweise: • In Java berechnet % den Rest einer Ganzzahl-Division. So ist z.B. 7 7 % 3 == 1 und -7 % 3 == -1. Programmierung WS11/12 Lösung - Übung 1 Lösung: public class GeradeQuadrat { public static void main ( String [] args ) { System . out . println ( " Bitte geben Sie eine Zahl ein : " ); int i = Integer . parseInt ( System . console (). readLine ()); System . out . print ( " Die eingegebene Zahl ist " ); System . out . println ( i % 2 == 0 ? " gerade . " : " ungerade . " ); System . out . println ( " Wie lautet das Quadrat dieser Zahl ? " ); int j = Integer . parseInt ( System . console (). readLine ()); System . out . print ( " Die Antwort ist " ); System . out . println ( i * i == j ? " korrekt . " : " falsch . " + " Die korrekte Antwort ist " + ( i * i ) + " . " ); } } . 8