Programmieren 1

Download Report

Transcript Programmieren 1

FB Informatik
Prof. Dr. R.Nitsch
Programmieren 1 – Kontrollstrukturen Teil 2
Reiner Nitsch
Homepage mit Skript und Materialien zu PG1:
www.fbi.h-da.de/~r.nitsch
Hinweise:
Die in diesem Kapitel beschriebenen Kontrollstrukturen werden im E-Book auf den
Seiten 73-84 behandelt. ich bitte Sie, dieses Skript und/oder die entsprechenden Seiten
im E-Book durchzuarbeiten. Bei der Wiederaufnahme des Vorlesungsbetriebs werden
diese Themen nicht mehr behandelt und als bekannt vorausgesetzt.
Selbstverständlich bekommen Sie Fragen zu den hier behandelten Themen in der
Vorlesung beantwortet.
Kontrollstruktur – Mehrfache Auswahl mit switch – case /73/
A
w1
w2
…
wn
S1
S2
…
Sn
In den beiden Diagrammen steht A für einen Ausdruck, der
stets einen der (ganzzahligen) Werte w1, w2, . . . ergibt. Der
unter dem entsprechenden wi stehende Strukturblock Si wird
ausgeführt.
Es gibt folgende Variante, bei der der Strukturblock S unter
'sonst' aufgeführt wird, falls A nicht einen der wi ergibt:
A
w1
w2
…
sonst
S1
S2
…
S
C++ kann das nur bedingt:
switch ( A ) {
case w1: S1; break;
case w2: S2; break;
case wn: Sn; break;
default: S; break;
}
Optional; muss nicht
letzte Marke sein.
29.04.2020
FB Informatik
Prof. Dr. R.Nitsch
Beispiel: Menüsteuerung
char Option
do {
cout << "Moegliche Optionen: a/b/x\n"
muss ganzzahliger
"Gib Option: ";
Ergebnis-Typ sein
cin >> Option;
switch (Option) {
break verzweigt
case 'a': S1(); break;
hinter das Ende
case 'b': S2(); break;
der switchcase 'x': cout << "Programmende"; break;
Anweisung
default: cout << "Option gibt es nicht!";
optional
}
} while (Option != 'x');
2
Ziffern, Zwischenraum und andere Zeichen zählen
FB Informatik
Prof. Dr. R.Nitsch
void main () {
In C++ können Zeichen in jedem
char c;
Ganzzahltyp gespeichert werden, da
int whitespace(0), number(0), other(0);
sie intern als 1-byte-Ganzzahlen
do {
dargestellt werden.
c = cin.get();
switch (c) {
Liest genau ein Zeichen von Tastatur ein. Notwendig, weil
case ' ':
cin Zwischenraumzeichen entfernt.
case '\n':
case '\t': whitespace++; break;
Sentinel ist EOF (iostream)
case '0': case '1': case '2': case '3':
"End of File"; Wert = -1;
case '4': case '5': case '6': case '7':
Eingabe plattformabhängig
case '8': case '9': number++; break;
(Windows: ctrl-Z).
default: other++; break;
EOF muß am Zeilenanfang stehen.
}
sonst wird es von cin ingnoriert
} while ( c!= EOF );
--other;
cout << "\nDie Eingabe enthielt" << endl
<< number << " Ziffern" << endl
<< whitespace << " Zwischenraumzeichen "
<< "und" << endl
<< other << " andere Zeichen." << endl;
und der Eingabepuffer gelöscht
Das newline-Zeichen am
Ende jeder Eingabe darf
nicht mitgezählt werden.
}
29.04.2020
3
Annehmende Schleife /77-79/ – do while
FB Informatik
Prof. Dr. R.Nitsch
Schleife mit nachfolgender Bedingungsprüfung: annehmende Schleife
S
Mit B wird eine Bedingung (logischer Ausdruck)
bezeichnet, S ist ein Strukturblock.
Zuerst wird S ausgeführt, danach wird B getestet.
Ergibt dieser Test false, so wird der nächste
Strukturblock verarbeitet. Liefert der Test true, so
wird der vorliegende Strukturblock S erneut
ausgeführt.
B
C++ Syntax:
do {
//Anweisungen aus S
} while (B);
Unterschied zur annehmenden Schleife: S wird mindestens einmal ausgeführt!
Empfehlung: Nur anwenden in begründeten Ausnahmefällen, z.B. wiederholte Benutzereingabe
Beispiel 1
Vom Benutzer eingegebene positive Zahlen
sollen aufsummiert werden.
int Counter::accumulate() {
int nextVal;
Schleifenvariable
value = 0;
Rückgabewert initialisieren
do {
nextVal = get_int("Gib Ganzzahl>0");
Schleifenvariable Richtung Ziel verändern
value += nextVal;
"Nutzleistung"
} while ( nextVal >0 ); value-=nextVal;
return value;
sentinel: nextVal<0
}
Achtung: Sentinelwert wird auch addiert! Was nun?
29.04.2020
4
Annehmende Schleife – do while
Beispiel 2
void Counter::countdown() {
// PRE: 0<=value
if( value==0 )
throw std::runtime_error();
do {
cout << value << endl;
--value;
>0
} while (value
);
cout << 0 << endl;
assert (value == 0 );
}
FB Informatik
Prof. Dr. R.Nitsch
1. Wichtig: Zuerst die Zusicherungen.
Daraus ergeben sich die notwendigen
lokalen Variablen!
2. Algorithmus schreiben und
Prüfbedingung festlegen.
3. Prüfen des Algorithmus mit Extremwerten:
ok
wert = 1
wert > 1 ; z.B wert = 2 ok
Frage: Ist das übersetzungsfähig?
Compilermeldung: 'c': nichtdeklarierter Bezeichner
do
{
Begründung: Speicherklasse von c ist "auto", d.h.
c ist lokale Variable im Strukturblock S
c ist nur im Strukturblock S definert!
Gültigkeitsbereich von c endet mit '}'
char c;
cin >> c;
}
while ( c != '*' );
29.04.2020
Diese Schleife
endet nie!
char c = ' ';
while ( c != '*' ) {
char c; cin>>c; cout<<c;
}
5
Schleife mit fester Wiederholungsanzahl /80-84/ - for
FB Informatik
Prof. Dr. R.Nitsch
Eigentlich überflüssig, aber von Programmierern gern benutzt
C++ Syntax
SV initialisieren
Solange Bedingung B
wahr (≠0) ist
S
ist äquivalent zu
for ( SVinit; B; SVincrement)
S;
SV verändern
Richtung Ziel
S
Beispiel: Quadratzahltabelle
for ( int i = 1; i <= 3; i++ )
1
2
cout << i << i*i << endl;
3
4
SV Initialisierung!
C++: Gültigkeitsbereich von i ist nur die for-Anweisung.
d.h.
for( int i=0; i<10; ++i ) { … }
i = 0;
quittiert der C++ Compiler mit Fehlermeldung: 'i': nichtdeklarierter Bezeichner
29.04.2020
SVinit
while (B) {
S
SVincrement
}
Ausgabe
1
2
3
1
4
9
6
Einfache Beispiele für for - Anweisung
FB Informatik
Prof. Dr. R.Nitsch
a ) Dekrementieren der SV in Schritten von 1
for ( int i=5 ; i>=1 ; i-- ) {
cout << i << ' '; }
Ausgabe:
54321
Ausgabe:
7 14 21 28 35
Ausgabe:
10 8 6 4 2
b ) Inkrementieren der SV in Schritten > 1
for ( int i=7 ; i<=35 ; i+=7 ) {
cout << i << ' '; }
c ) Dekrementieren der SV in Schritten > 1
for ( int i=10 ; i>=2 ; i-=2 ) {
cout << i << ' '; }
29.04.2020
7
Schleife mit fester Wiederholungsanzahl - for
Beispiel: countdown
void Counter::countdown()
{
if( value<=0 )
throw std::runtime_error();
for ( ; value >0 ; --value )
cout << value << endl;
cout << 0 << endl;
assert (value == 0 );
}
FB Informatik
Prof. Dr. R.Nitsch
1. Wichtig: Zuerst die Zusicherungen.
Daraus ergeben sich die notwendigen
lokalen Variablen!
2. Algorithmus schreiben und
Prüfbedingung festlegen.
3. Prüfen des Algorithmus mit Extremwerten
und ggf. Prüfbedingung/Algorithmus
korrigieren :
value = 1
value > 1 ; z.B value = 2
Jeder der 3 Ausdrücke in for-Anweisung kann weggelassen werden:
Beispiel
29.04.2020
for ( ; ; )
cout << "Wird nie fertig"
besser
for ( ; true ; ) S
8
Schleife mit fester Wiederholungsanzahl - for
Beispiel: GGT zweier Ganzzahlen mit for
Lösung mit Pseudocode
• Vorbedingung? Nachbedingung?
• Schleifenvariable ggT mit Minimum beider Zahlen initialisieren
• Prüfen, ob beide Zahlen ohne Rest durch ggT teilbar sind
• Falls ja, Schleife verlassen und mit nächster Anweisung fortfahren
• Falls nein, ggT um eins vermindern
29.04.2020
FB Informatik
Prof. Dr. R.Nitsch
 Hausaufgabe
9
Der Komma-Operator
FB Informatik
Prof. Dr. R.Nitsch
 meist in for-Anweisung verwendet
 erlaubt dort mehrere Ausdrücke, wo syntaktisch nur 1 Ausdruck stehen darf
 hat den niedrigsten Vorrang
 wertet von links nach rechts aus
 Gesamtausdruck hat den Wert des ganz rechts stehenden Ausdrucks
Beispiel 1
int i, j, summe(0);
for ( i = 100 , j=1; j < i; i-- , j++ )
summe += i + j;
cout << summe;
Was leistet diese Anwendung?
// Addiert (1+100)+(2+99)+…+(50+51) = 5050
// Sinnvolle Anwendung des Kommaoperators
// Summe der Zahlen von 1 bis 100
// wird berechnet
Beispiel 2
int i,j;
int z = ( i=20, j=2*i);
Welche Werte werden zugewiesen?
// i = 20, j = 40, z = 40
// kein guter Programmierstil!
Warum muss hier geklammert werden?
29.04.2020
Fehler: int j: Neudefinition
11
FB Informatik
Prof. Dr. R.Nitsch
So, das war´s erst mal!
29.04.2020
12