Post on 09-Aug-2020
Informatik - Ubungsstunde
Jonas Lauener (jlauener@student.ethz.ch)
ETH Zurich
Woche 10 - 08.05.2018
Lernziele
− (E)BNF - (Extended) Backus-Naur-Form
− Structs
− Function overloading
− Operator overloading
− Tribool
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 2 / 24
(E)BNF - (Extended) Backus-Naur-Form
− Eine Anzahl Regeln, die alle erlaubten Sequenzen von Zeichenbeschreibt
− Diese nennt man Satze.
− Funktioniert rekursiv
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 3 / 24
(E)BNF - Beispiel
− Alphabet: {A, a, _}
− Regeln:
− A darf nur nach einem Bodenstrich oder als erstes Symbolvorkommen.
− durfen nicht in Paaren oder am Anfang oder am Schluss derSequenz vorkommen.
− Erlaubt: Aaaaa aaa
− Nicht erlaubt: AaaaaAaa
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 4 / 24
EBNF - Beispiel
− Regeln in neuer Form:
− seq = term | term "_" seq
− term = "A" | "A" lowerterm | lowerterm
− lowerterm = "a" | "a" lowerterm
− | trennt die moglichen Optionen
→ Problem: lowerterm nicht klar definiert
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 5 / 24
EBNF - Beispiel
− Regeln in neuer Form:
− seq = term | term "_" seq
− term = "A" | "A" lowerterm | lowerterm
− lowerterm = "a" | "a" lowerterm
− | trennt die moglichen Optionen
→ Problem: lowerterm nicht klar definiert
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 5 / 24
EBNF - Beispiel
Losung mit EBNF:
− seq = term | term "_" seq
− term = "A" { "a" } | "a" { "a" }
− Zusatzlicher Syntax: { ... }
Inhalt in Klammern kann 0...n Mal wiederholt werden
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 6 / 24
EBNF - Beispiel
Weitere Vereinfachung:
− seq = term [ "_" seq ]
− term = "A" { "a" } | "a" { "a" }
− Zusatzlicher Syntax: [ ... ]
Inhalt in Klammern kann 0 oder 1 Mal wiederholt werden
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 7 / 24
Structs
− Moglichkeit um ein Gruppe von verschiedenen Datentypen in einObjekt zu packen
→ Container fur thematisch zusammengehorende Daten
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 8 / 24
Structs
1 struct rational {
2 int n;
3 int d; // INV: d != 0
4 }; // ; nicht vergessen!
5
6 int main () {
7 // Element -wise initialization
8 rational r;
9 r.n = 1;
10 r.d = 2;
11
12 // Initializer list
13 rational d = {1, 2};
14
15 // "Incomplete" initializer list
16 rational g = {1};
17 // g.n == 1 und g.d == 0
18 }
− Vergesst das Semikolon nicht!
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 9 / 24
Structs
1 struct strange {
2 int n;
3 bool b;
4 int a[3];
5 };
6 int main () {
7 // Element -wise initialization
8 strange x;
9 x.n = 1;
10 x.b = true;
11 x.a[0] = 1;
12 x.a[1] = 2;
13 x.a[2] = 3;
14 // Initializer list
15 strange d = {1, true , {1,2,3}};
16 // C++ can copy C arrays this way
17 strange y = x;
18 }Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 10 / 24
Old Exam QuestionFeb. 2010, Ex. 5
Exercise
In this exercise we will implement a representation of3D-geometrical objects in a computer game.
Given is a struct point which stores 3D-points.
2
struct point {
double x, y, z;
};
(x,y,z)
(From: Exam Feb. 2010, Ex. 5)
Exercise a)
(From: Exam Feb. 2010, Ex. 5) 3
// POST: returns the distance between p and
// the origin
double distance(const point& p);
struct point {
double x, y, z;
};
(x,y,z)
Exercise a)
Implement the following function which computes the distance between a given point and the origin.
Hint: The function std::sqrt (double d) computes thesquare root of d.
Exercise a)
(From: Exam Feb. 2010, Ex. 5) 4
// POST: returns the distance between p and the origin
double distance(const point& p) {
return std::sqrt(p.x * p.x + p.y * p.y + p.z * p.z);
}
Solution a)
Exercise b)
(From: Exam Feb. 2010, Ex. 5) 5
struct point {
double x, y, z;
};
(x,y,z)
Exercise b)
Propose a struct named line, which can be used torepresent 3D-straight-lines.
A particular straight line does not have to be representableuniquely, but conversely every object of type line has torepresent a unique straight line. If necessary you can for thisreason define a suitable invariant (// INV:...) which hasto be met when using the line struct.
Exercise b)
(From: Exam Feb. 2010, Ex. 5) 6
line
Solution b)
Exercise b)
(From: Exam Feb. 2010, Ex. 5) 7
line
Two different points
unique line
Solution b)
Exercise b)
(From: Exam Feb. 2010, Ex. 5) 8
struct line {
point a, b; // INV: a != b
};
Solution b)
Exercise c)
(From: Exam Feb. 2010, Ex. 5) 9
struct line {
point a, b; // INV: a != b
};
// POST: returns a straight line through a and b
line compute_line (const point& a, const point& b);
struct point {
double x, y, z;
};
Exercise c)
Based on your struct line implement the following function whichcomputes the straight line through two points.
Make sure to meet your invariant from part b). You should defineand verify a suitable PRE-condition for this reason.
Exercise c)
(From: Exam Feb. 2010, Ex. 5) 10
// PRE: a != b
// POST: returns a straight line through a and b
line compute_line (const point& a, const point& b) {
line g;
g.a = a;
g.b = b;
return g;
}
Solution c)
assert( (a.x != b.x) && (a.y != b.y) && (a.z != b.z) );
Function overloading
− Mehrere Funktion mit dem gleichen Namen− Mussen jedoch eindeutig unterscheidbar sein!− Unterscheidung durch Anzahl Parameter:
1 int f (int a) {
2 ...
3 }
4 int f (int a, int b) {
5 ...
6 }
− Unterscheidung durch Parametertyp:
1 int f (int a) {
2 ...
3 }
4 int f (float a) {
5 ...
6 }
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 11 / 24
Function overloading
1 int f (int a) {
2 ...
3 }
4 int f (int b) {
5 ...
6 }
Geht dieses Overloading?
Nein! Denn der Parametername wird bei Aufruf nicht benutzt.
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 12 / 24
Function overloading
1 int f (int a) {
2 ...
3 }
4 int f (int b) {
5 ...
6 }
Geht dieses Overloading?Nein! Denn der Parametername wird bei Aufruf nicht benutzt.
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 12 / 24
Function overloading
1 int f (int a) {
2 ...
3 }
4 double f (int a) {
5 ...
6 }
Geht dieses Overloading?
Nein!
1 void caller () {
2 f(1); // call without return type
3 // what function should be called?
4 }
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 13 / 24
Function overloading
1 int f (int a) {
2 ...
3 }
4 double f (int a) {
5 ...
6 }
Geht dieses Overloading?Nein!
1 void caller () {
2 f(1); // call without return type
3 // what function should be called?
4 }
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 13 / 24
Function overloading - Regeln
Erlaubt
− Unterscheidung durch Anzahl Argumente
− Unterscheidung durch Typ der Argumente
Nicht erlaubt:
− Name des Arguments
− Ruckgabetyp
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 14 / 24
Function Overloading
1 double calculation (double value) {
2 return value / 2.0;
3 }
4
5 int main () {
6 int number;
7 std::cin >> number;
8 double result = calculation(number);
9 std::cout << result;
10 return 0;
11 }
Was passiert, wenn number = 15 ist?
Resultat: 7.5
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 15 / 24
Function Overloading
1 double calculation (double value) {
2 return value / 2.0;
3 }
4
5 int main () {
6 int number;
7 std::cin >> number;
8 double result = calculation(number);
9 std::cout << result;
10 return 0;
11 }
Was passiert, wenn number = 15 ist? Resultat: 7.5
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 15 / 24
Function Overloading
1 int calculation (int value) {
2 return value / 2;
3 }
4
5 double calculation (double value) {
6 return value / 2.0;
7 }
8
9 int main () {
10 int number;
11 std::cin >> number;
12 double result = calculation(number);
13 std::cout << result;
14 return 0;
15 }
Was passiert, wenn number = 15 ist?
Resultat: 7
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 16 / 24
Function Overloading
1 int calculation (int value) {
2 return value / 2;
3 }
4
5 double calculation (double value) {
6 return value / 2.0;
7 }
8
9 int main () {
10 int number;
11 std::cin >> number;
12 double result = calculation(number);
13 std::cout << result;
14 return 0;
15 }
Was passiert, wenn number = 15 ist? Resultat: 7
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 16 / 24
Operator overloading
1 rational& operator += (rational& a, const
rational b) {
2 a.n = a.n * b.d + a.d * b.n;
3 a.d *= b.d;
4 return a;
5 }
6 ...
7 a += b;
8 operator +=(a, b); // equivalent
− Warum Referenz als Ruckgabetyp?
− Analog fur − =, ∗ =, / =
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 17 / 24
Operator overloading
1 rational operator+ (rational a, const
rational b) {
2 return a += b;
3 }
4 ...
5 rational t = a + b;
6 rational t = operator +(a, b); // equivalent
− Analog fur ∗, −, /
− Definition fur += wird benutzt → weniger Redundanz
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 18 / 24
Operator overloading
Von alt:
1 struct rational {
2 int n;
3 int d; // INV: d != 0
4 };
Zu neu:
1 struct rational {
2 bool sign;
3 unsigned int n;
4 unsigned int d; // INV: d != 0
5 };
Nur + = etc. mussen dann angepasst werden und nicht auch + etc.
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 19 / 24
Operator overloading - Pre- und Postincrement
Preincrement:
1 rational& operator ++ (rational& r) {
2 rational s = {1 ,1};
3 return r += s;
4 }
Postincrement:
1 rational operator ++ (rational& r, int i) {
2 rational s = {1 ,1};
3 rational r_0 = r;
4 r += s;
5 return r_0;
6 }
→ Unterscheidung durch dummy variable i (i wird nie benutzt)
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 20 / 24
Operator overloading
1 std:: ostream& operator << (std:: ostream& o,
rational r) {
2 o << r.n << "/" << r.d;
3 return o;
4 }
5 ...
6 rational a = {2, 5}
7 std::cout << a << std::endl; // output: 2/5
− Ubergabe von Outstream als Referenz, da wir Streams nichtkopieren konnen.
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 21 / 24
Operator overloading - Regeln
− (Fast) alle Operatoren in C++ konnen uberladen werdenAusnahmen:
− conditional (?:)− sizeof
− scope (::)− member selector (.)− member pointer selector (.*)
− Nur existierende Operatoren konnen uberladen werden→ kein **-Operator definierbar
− Min. ein Operand/Parameter muss ein selbst-definierter Typ sein→ kein neuer +-Operator mit den Parameter float und intdefinierbar, aber mit float und rational geht
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 22 / 24
Tipps zu den Ubungen
− Task 1) Neue Zahl definieren mit Wertebereich von 0 bis 7 (3bit-System) & Modulo 7 nutzen
− Task 2a)
− std:: istream& operator >>(
std:: istream& i, Complex c) fur Eingabe− Char einlesen: char b; std::cin >>b;
− Arithmetische Operationen: Besser zuerst gut uberlegen undnachlesen, wie das bei komplexen Zahlen geht, bevor manlange coded.
− (a + bi)(c + di) = (ac − bd) + (bc + ad)i
− a+ibc+id = (a+ib)(c−id)
(c+id)(c−id)− Benutzt die gegebene Main-Funktion erst, wenn ihr glaubt,
fertig zu sein. Vorher nur Teile debuggen.
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 23 / 24
Code Style
− Code einrucken
− Variablenamen in Englisch
− Codeblocke kommentieren
− Statement nach if/else/for/while immer mit {} umschliessen
− PRE- und POST-Condition fur jede Funktion
Jonas Lauener (ETH Zurich) Informatik - Ubung Woche 10 24 / 24