(251-0832-00) D-MAVT F2010 Kontrollanweisungen 1, ASCII

Werbung
Informatik 1 (251-0832-00)
D-MAVT
F2010
Kontrollanweisungen 1,
ASCII
Yves Brise
20100317 - Übungsstunde 3
Inhalt
Ziele:
• Prüfungsaufgabe
• Festigung & Repetition
• Kontrollstrukturen
Bemerkung zu Übungsabgabe:
Wenn möglich die Zeilenlänge in Dateien auf 80
beschränken. Lässt sich besser drucken.
Yves Brise
20100317 - Übungsstunde 3
Prüfungsaufgabe
Deklarieren sie a, b und c so, dass die nachfolgenden
Anweisungen fehlerfrei kompilieren und nicht implizit
konvertiert wird.
i) a = 5; b = a < 3; c = ‘4’;
ii) a = b || char(c-5) == ‘b’;
Lösung:
i) int a; bool b; char c;
ii) bool a, b; int c;
Yves Brise
20100317 - Übungsstunde 3
Deklarieren vs Definieren
Deklaration
Wir sagen dem Compiler, wie ein Objekt heisst. Es wird kein
Speicher reserviert.
Z.B.Variablendeklaration, Funktionsdeklaration, Klassendeklaration.
int a;
int my_function(double p);
class my_agent;
Definition
Wir sagen dem Compiler, wie ein Objekt heisst, aber auch wie es
implementiert ist (resp. was für einen Wert es hat).
int a = 1;
int my_function(double p) {...}
class my_agent {...};
Yves Brise
20100317 - Übungsstunde 3
Typ, Wert und Effekt
int a;
a = 3;
Die Zweite Anweisung hat den Typ int, den Wert 3 und
den Effekt, dass der Variable a 3 zugewiesen wird.
Typ int, Wert 2 und die Effekte, dass a neu
den Wert 2 und b neu den Wert 1 hat.
int a(1), b(0);
a += ++b;
std::cout << ”Hallo”;
Typ std::ostream&, Wert ist eine Adresse, Effekt ist, dass “Hallo”
auf den Ausgabestrom geschrieben wird.
Typ int, Wert vermutlich 0, Effekt ist, dass
die main Funktion ausgeführt wird...
Yves Brise
main();
20100317 - Übungsstunde 3
Schnellübung
Diskutieren Sie Typ, Wert und Effekt der folgenden
Anweisungen.
Lösung: Der Typ ist immer int.
a) Wert 35 als rvalue, Effekt: a
wird 5 und b wird 7 zugewiesen.
b) Wert 5 als lvalue, Effekt: a und
b wird beiden 5 zugewiesen.
c) Wert 5 als lvalue, Effekt: a wird
5 zugewiesen.
d) ungültig, da a*3 ein lvalue ist.
e) undefiniert.
int a(0), b(1);
a) (a=5)*(b=7);
b) a=(b=5);
c) (a=b)=5;
d) (a*3)=(b*5);
e) (a=b)*(b=5);
Yves Brise
20100317 - Übungsstunde 3
Sequenzen von + und Gruppierungsregel
Wenn mehrere + oder - Zeichen aufeinander folgen, dann
werden sie von links nach rechts zu Paaren
zusammengefasst. Unter Umständen bleibt dann ganz
rechts ein Zeichen übrig.
ok
Bsp.
a+++b;
a+(+(+b)), a+(++b), (a++)+b
a++b;
a+(+b), (a++)b
---a;
-(-(-a), -(--a), --(-a)
nok
Yves Brise
20100317 - Übungsstunde 3
Schrittweise Auswertung
Nicht nur das Endresultat zählt, sondern auch die
Zwischenschritte! Vgl. short-circuit evaluation (auch unter
dem Begriff lazy evaluation subsumiert).
Bsp:
!(9 % 2) || 9 % 3
!(1) || 9 % 3
!true || 9 % 3
Solange wir nicht wissen, was auf der
linken Seite steht, rühren wir die
rechte Seite nicht an. In Schritt 3
finden wir, dass die linke Seite false
ist. Das heisst kein Kurzschluss.
false || 9 % 3
false || 0
false || false
false
Alternativ:
true || 9 % 3
true
Yves Brise
Kurzschluss!
20100317 - Übungsstunde 3
ASCII
Yves Brise
20100317 - Übungsstunde 3
“Rechnen” mit ASCII
Der Typ char ist nichts anderes als eine ganze Zahl mit
kleinerem Wertebereich als int.
char c = ’A’;
for (int i = 0; i < 26; ++i) {
std::cout << static_cast<char>(c + i);
}
Anderes Beispiel: Konvertieren zu Ziffern
char c = ’9’;
int a = c - ’0’;
std::cout << a << ” has ASCII code ” << static_cast<int>(c);
Yves Brise
20100317 - Übungsstunde 3
Konstanten
1. Möglichkeit
#define PI 3.14159
Vorteil: Braucht keinen Speicher. Wird vom
Präprozessor erledigt. Einfache Textersetzung.
Nachteil: Berücksichtigt keine
Gültigkeitsbereiche und bei komplizierteren
Definitionen (Makros) kann es zu
unerwünschten Nebeneffekten kommen (Vgl.
Beispiel max aus der Vorlesung).
Yves Brise
20100317 - Übungsstunde 3
Konstanten
2. Möglichkeit
const double pi = 3.14159;
Nachteil: Braucht Speicher
Vorteil: Respektiert Gültigkeitsbereiche, d.h.
keine Ersetzung an unerwünschten Stellen.
Bessere Diagnostik, bei Fehlersuche.
const int NUMBER = -42;
int main() {
int x = -NUMBER;
}
Yves Brise
#define NUMBER -42
int main() {
int x = -NUMBER;
}
20100317 - Übungsstunde 3
Fehler
Konstanten
Const Richtline
Immer wenn man eine Variable definiert, sollte man sich
fragen, ob der Wert verändert werden soll. Falls nein, dann
ist ein const zu setzen.
Yves Brise
20100317 - Übungsstunde 3
if-then-else Anweisung
if (condition) {
...
} else {
...
}
Kurzform...
Praktisch für Einzeiler.
Bei einer einzlenen Anweisung
kann der Block weggelassen
werden. Meine Empfehlung:
Klammern IMMER setzen.
Vorteile: Lesbarkeit, Robustheit
condition ? expr1 : expr2
std::cout << (a>0 ? ”Pos” : ”Neg”);
Yves Brise
20100317 - Übungsstunde 3
Lösen quadratischer Gleichungen
Aufgabe: Schreiben Sie ein Programm, welches drei
Zahlen a, b und c einliest und anschliessend die reellen
Lösungen der quadratischen Gleichung ax 2 + bx + c = 0
berechnet.
√
−b ± b 2 − 4ac
Zur Erinnerung: x1,2 =
2a
Ausgabe: “Es gibt k Lösungen”, wobei k=0,1,2, gefolgt von
den Lösungen. Oder “Es gibt unendlich viele Lösungen”.
Hilfestellung:
• Überprüfen Sie zuerst, ob a Null ist. Falls nicht, dann
2
überprüfen Sie, ob b − 4ac Null oder negativ ist.
• Wurzelziehen mit std::sqrt(double)
Yves Brise
20100317 - Übungsstunde 3
Lösen quadratischer Gleichungen
double s1(0.0), s2(0.0);
int n(0);
if (a == 0.0)
// linear case: bx + c = 0
if (b == 0.0)
// trivial case: c = 0
if (c == 0.0)
n = -1; // => infinitely
else
n = 0; // => no solution
else {
// bx + c = 0, b != 0
=>
s1 = -c/b;
n = 1;
}
else {
double d = b*b-4.0*a*c;
if (d == 0.0) {
// ax^2 + bx + c = 0, a !=
s1 = -b / (2.0*a);
n = 1;
} else {
// ax^2 + bx + c = 0, a !=
s1 = (-b + std::sqrt(d)) /
s2 = (-b - std::sqrt(d)) /
n = 2;
}
}
Siehe Datei
solve_quad_eq.cpp.
many solutions
one solution
0, d==0 => one solution
0, d!=0 => two solutions
(2.0*a);
(2.0*a);
Yves Brise
Lösung dort ist noch ein
wenig ausgereifter als die
nebenstehende. Es werden
Funktionen und der Typ
complex<double> aus
dem Namensraum std
verwendet.
Lösung hier noch
unvollständig für reelle
Zahlen. Es wird nicht
geprüft, ob d<0.
20100317 - Übungsstunde 3
switch Anweisung
• Anhand der Auswertung von
switch (expr) {
case <val1>:
...
break;
case <val2>:
...
break;
default:
...
}
expr wird entschieden,
wohin gesprungen wird.
• Von der Sprungstelle geht die
Auswertung einfach
sequentiell weiter, d.h. die
cases werden ignoriert.
• Die Anweisung break
beendet die Ausführung des
switch. Kann man auch bei
do, for und while
gebrauchen.
Yves Brise
20100317 - Übungsstunde 3
Ziffern extrahieren
In Aufgabe 5 müssen Sie die Ziffern einer ganzen Zahl
extrahieren. Im Allgemeinen:
int a(...); // Positive ganze Zahl kleiner als 2^31
int digits[10]; // Feld (Array) für die Ziffern
int b(10); // Basis des Zahlensystems
for (int i = 0; a > 0; ++i) {
digits[i] = a % b; // letzte Stelle extrahieren
a /= b; // letzte Stelle wegschmeissen
}
Am Ende stehen die Ziffern in digits[0], digits[1], ...,
geordnet von der am wenigsten signifikanten zur am meisten
signifikanten.
Yves Brise
20100317 - Übungsstunde 3
Ziffern extrahieren
Im Speziellen für Aufgabe 5. Wir wissen, dass wir nur Zahlen
kleiner 100 betrachten, d.h. maximal 2 Stellen.
int a(...); // Positive ganze Zahl kleiner als 100
int einer(0), zehner(0);
einer = a % 10;
zehner = a / 10;
Genau das selbe Prinzip, aber für eine fixe Anzahl von Stellen.
Yves Brise
20100317 - Übungsstunde 3
Tipps zu Serie 3
Aufgaben 1, 2: Machen Sie schrittweise Auswertung.
Aufgaben 3: Erstens: 5 ist kein echter Teiler von 5.
Zweitens: Die Bibliothek cmath enthält eine Funktion
abs, um den Absolutwert zu berechnen.
Aufgaben 4: Sehr ähnlich wie das Lösen quadratischer
Gleichungen → Determinanten ausrechnen und Fälle
unterscheiden.
Aufgaben 5: Siehe Tipps auf dem Übungsblatt
und das Extrahieren der Ziffern, das wir heute
gesehen haben. Was nicht erwähnt ist, sind
negative Zahlen. Überlegen Sie sich, was Sie in
diesem Fall tun wollen.
Yves Brise
20100317 - Übungsstunde 3
Herunterladen