C++-Programmieranleitung mit Musteraufgaben

Werbung
Prof. Dr.-Ing. Alfred Busse
Hochschulübergreifender Studiengang
Wirtschaftsingenieurwesen (HWI)
HAW Hamburg
C++-Programmieranleitung
mit
Musteraufgaben
Studiengang:
Wirtschaftsingenieurwesen (3. Sem.)
Umfang:
1 SWS (1 Ü)
Stand:
SS 02
Letzte Änderung: 05.07.2002
Copyright:
 Busse (dr.b.)
nur für persönliche Studienzwecke im HWI
keine Lagerung auf fremden Servern
Inhaltsverzeichnis
1 Einführung in die Programmierung ................................................................ 4
2 Programmentwicklung in C++ ......................................................................... 6
3 Vorhandene Bedienoberfläche.......................................................................... 7
3.1 Hard- und Software-Umgebung ................................................................................... 7
3.2 Erste Hilfe ................................................................................................................... 7
4 Elementare C++-Programmierung .................................................................. 8
4.1 Der C++-Programmaufbau .......................................................................................... 8
4.1.1 Grundaufbau.................................................................................................... 8
4.1.2 Kommentare .................................................................................................... 8
4.1.3 Zuweisungsoperator......................................................................................... 9
4.2 Zahlenformate, Operatoren und mathem. Funktionen................................................. 10
4.2.1 Bestimmung der Speichergröße ..................................................................... 10
4.2.2 Wertebereich für den Typ int ......................................................................... 10
4.2.3 Wertebereich für den Typ short int................................................................. 11
4.2.4 Wertebereich für den Typ unsigned short int.................................................. 11
4.2.5 Übersicht der Wertebereiche.......................................................................... 12
4.2.6 Bit-Operatoren............................................................................................... 12
4.2.7 Logische Operatoren...................................................................................... 13
4.2.8 Relationale Operatoren .................................................................................. 14
4.2.9 Einige mathematische Funktionen ................................................................. 15
4.3 Ein- und Ausgabe ...................................................................................................... 16
4.3.1 Elementare Ein-/Ausgabe .............................................................................. 16
4.3.2 Stream-Technik ............................................................................................. 16
4.3.3 Einfache Manipulatoren................................................................................. 18
4.3.4 Escape-Sequenzen ......................................................................................... 19
4.3.5 Eingabe ......................................................................................................... 19
4.4 Einfache Rechenoperationen...................................................................................... 21
4.4.1 Addition, Multiplikation, Division, Modulo-Operator .................................... 21
4.4.2 Division mit Gleitkommazahlen .................................................................... 22
4.4.3 Inkrement-Operator ....................................................................................... 23
4.5 Schleifen und Bedingungen ....................................................................................... 24
4.5.1 Struktogrammelemente für C++..................................................................... 24
4.5.2 While-Schleife............................................................................................... 26
4.5.3 Do...while-Schleife ........................................................................................ 27
4.5.4 Switch-Anweisung......................................................................................... 28
4.5.5 Musteraufgabe „Fahrenheit“ .......................................................................... 30
4.5.6 For-Scheife .................................................................................................... 32
4.5.7 If-Anweisung................................................................................................. 34
4.5.8 Boolsche Variablen........................................................................................ 35
3D26E882-2673-8602.doc/05.07.02/dr.b.
2
4.5.9 Zeichen- und Zeichenketten........................................................................... 36
4.5.10 Einlesen von Tastaturzeichen....................................................................... 37
4.5.11 Kleine Musteraufgabe „Pole Position“ ......................................................... 38
4.5.12 Goto-Anweisung.......................................................................................... 39
4.5.13 Chaotische Programmierung ........................................................................ 40
4.5.14 Switch-Anweisung....................................................................................... 41
4.5.15 Musteraufgabe „PIN“ .................................................................................. 42
4.6 Unterprogramme........................................................................................................ 43
4.7 Datenfelder (Arrays) .................................................................................................. 44
4.7.1 Eindimensionale Arrays................................................................................. 44
4.7.2 Mehrdimensionale Arrays.............................................................................. 45
4.7.3 Musteraufgabe „Schachbrett“ ........................................................................ 46
5 Objektorientierte Programmierung ............................................................... 48
5.1 Methodischer Ansatz ................................................................................................. 48
5.1.1 Typen ............................................................................................................ 48
5.1.2 Klassen und Elemente.................................................................................... 48
5.1.3 Klassen deklarieren........................................................................................ 48
5.1.4 Objekte definieren ......................................................................................... 49
5.1.5 Auf Klassenelemente zugreifen...................................................................... 49
5.1.6 Definition einer Elementfunktion................................................................... 49
5.2 Musteraufgabe „Katzendatei“ .................................................................................... 50
6 Assembler-Programmierung .......................................................................... 52
7 Mathematische Methoden............................................................................... 53
7.1 Musteraufgabe „Sortieren“ ........................................................................................ 53
8 Weitere Beispielaufgaben................................................................................ 54
8.1 Musteraufgabe „Bruchkürzen“................................................................................... 54
8.2 Musteraufgabe „Geldautomat“................................................................................... 56
3D26E882-2673-8602.doc/05.07.02/dr.b.
3
1
Einführung in die Programmierung
Programmieren ist Teil des Software-Engineering und dient der Kommunikation
•
•
•
Mensch
Maschine
Mensch
=>
=>
=>
Maschine
Mensch
Maschine
=>
Mensch
Übliche Ansprüche sind
• Benutzerakzeptanz
• Ausbaufähigkeit
Software entwickeln = Programm schreiben
Die Standard-Entwicklungsphasen sind
•
Problemanalsyse + Anforderungsdefinition
=> Lastenheft / Pflichtenheft
(Was ist zu entwickeln?)
•
Entwurf
(wie ist es zu entwickeln?)
•
Implementierung
(Umsetzung in eine bestimmte Sprache)
•
Testen
(werden die Anforderungen erfüllt?)
•
Installation
(beim Kunden)
•
Nutzen
(Wartung + Pflege)
3D26E882-2673-8602.doc/05.07.02/dr.b.
4
Zeitwaufwand / Kosten
40 – 20 – 40 - Regel
Test + Installation
Implemetierung
Analyse + Entwurf
Das eigentliche „Programmschreiben“ nimmt nur ca. 20 % des gesamten Arbeitsumfangs
einer Software-Lösung ein!
3D26E882-2673-8602.doc/05.07.02/dr.b.
5
2
Programmentwicklung in C++
Problemstellung
Programmentwurf
Editor
Quelltext
Fehlerkorrektur
header-files
Präprozessor
weitere Quelltextmodule
„interner Quelltext“
Compiler
Objektmodul
weitere Objektmodule
Linker
Lader
Programmtest
lauffähiges Programm
3D26E882-2673-8602.doc/05.07.02/dr.b.
6
3
Vorhandene Bedienoberfläche
3.1
Hard- und Software-Umgebung
WindowsNT Workstations im FH-Bergedorfer Intranet.
Entwicklungsplattform:
Borland C++ V5.0
IDE =
=
3.2
integrated develpment environement
integrierte Enwicklungsumgebung
Erste Hilfe
/*
0. Zum Einloggen nach 16 Uhr ist ab sofort
eine eigene Nutzerkennung erforderlich.
Diese kann über die Homepage des Bergedorfer RZ beantragt werden.
1. Neue Quelldateien auf N: => in Ihr heutiges
Arbeitsverzeichnis laden
2. Dateinamen auf 8.3-Format ändern!!!
3. Für jede Arbeitssitzung ein Verzeichnis auf C: anlegen
z.B. alfred oder hilde, heinz
wichtig: nicht länger als 8 Zeichen!
Reihenfoge
a Quelltext schreiben und speichern
b Projekt anlegen:
Datei => neu => Projekt
zu empfehlen: Projektname = Dateiname
z.B
21dwhile.ide aus 21dwhile.cpp
dann: easywin => return
4. Bei Fehlschlag:
* Einzelne Fenster schließen
* Borland schließen
* alle beim Compilieren entstandenen Datein löschen
außer Quelldateien (Explorer: C++ Source File)!!!
* ggf. Quelldatei umbenennen
5. Nach Abschluß bitte Ihre Arbeit von Festplatte löschen.
3D26E882-2673-8602.doc/05.07.02/dr.b.
7
4
Elementare C++-Programmierung
4.1
Der C++-Programmaufbau
4.1.1
Grundaufbau
Der Rumpf eines typischen C++_Programms
// Beschreibung
#include <iostream.h>
int main()
{
// hier steht der eigentliche Programmkern
return(0);
}
Das erste C++-Programm
// Hello-World
#include <iostream.h>
int main()
{
cout << "Hello World!\n";
return (0);
}
4.1.2
Kommentare
// Programm Kommentar
#include <iostream.h> int main()
{
/* Das ist ein Kommentar, der
bis zum schließenden Kommentarzeichen aus
Sternchen und Schrägstrich geht */
cout << "Hello World!\n";
// Dieser Kommentar geht nur bis zum Zeilenende
cout << "Dieser Kommentar ist beendet!";
// Diese Kommentare können allein auf einer Zeile stehen
/* genau wie diese Kommentare */
return (0);
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
8
4.1.3
Zuweisungsoperator
// Programm Addition
#include <iostream.h>
int main ()
{
int sum1, sum2, sum3=10, a=16, b=20;
sum1 = 21+4;
/* Addition von Zahlenwerten
= ist der Zuweisungsoperator
( kein Gleichheitszeichen im mathem. Sinne
Die Addition wird durch das + Zeichen
in der CPU durchgeführt und das Ergebnis wird in die
Speicherzelle namens sum1 eingespeichert */
sum2 = a+b;
/* Addition von Variablen
genauer: es werden die Inhalte der Zellen a und b
addiert und das Ergebnis wird in sum2 abgespeichert
*/
cout << "sum3= " << sum3 << "\n";
sum3 = sum3 + 6;
/* Es wird von der CPU der Inhalt der Zelle sum3
eingelesen, dann wird 6 hinzuaddiert und dann wird
das Ergebnis nach sum3 eingespeichert
*/
cout << "sum1 = " << sum1 << "\n"
<< "sum2 = " << sum2 << "\n"
<< "sum3 = " << sum3 << "\n"
;
return (0);
}
//
{} Verbundoperator
3D26E882-2673-8602.doc/05.07.02/dr.b.
9
4.2
Zahlenformate, Operatoren und mathem. Funktionen
4.2.1
Bestimmung der Speichergröße
#include <iostream.h>
int main()
{
cout <<
cout <<
cout <<
cout <<
cout <<
cout <<
"Groesse
"Groesse
"Groesse
"Groesse
"Groesse
"Groesse
eines
eines
eines
eines
eines
eines
int:\t\t"
short int:\t"
long int:\t\t"
char:\t\t"
float:\t\t"
double:\t\t"
<<
<<
<<
<<
<<
<<
sizeof(int)
sizeof(short)
sizeof(long)
sizeof(char)
sizeof(float)
sizeof(double)
<<
<<
<<
<<
<<
<<
"
"
"
"
"
"
Bytes.\n";
Bytes.\n";
Bytes.\n";
Bytes.\n";
Bytes.\n";
Bytes.\n";
return 0;
}
4.2.2
Wertebereich für den Typ int
#include <iostream.h>
int main()
{
int Number;
Number = 32767;
cout << "Zahl: " << Number << endl;
Number++;
cout << "Zahl: " << Number << endl;
Number++;
cout << "Zahl: " << Number << endl;
return 0;
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
10
4.2.3
Wertebereich für den Typ short int
#include <iostream.h>
int main()
{
short int smallNumber;
smallNumber = 32767;
cout << "Kleine Zahl: " << smallNumber << endl;
smallNumber++;
cout << "Kleine Zahl: " << smallNumber << endl;
smallNumber++;
cout << "Kleine Zahl: " << smallNumber << endl;
return 0;
}
4.2.4
Wertebereich für den Typ unsigned short int
#include <iostream.h>
int main()
{
unsigned short int smallNumber;
smallNumber = 65535;
cout << "Kleine Zahl: " << smallNumber << endl;
smallNumber++;
cout << "Kleine Zahl: " << smallNumber << endl;
smallNumber++;
cout << "Kleine Zahl: " << smallNumber << endl;
return 0;
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
11
4.2.5
Übersicht der Wertebereiche
Wertebereich
(signed)
Wertebereich
(unsigned)
Anzahl der
Stellen
Typ
Byte
[un]signed char
1
-128..127
0..255
(entfällt)
[un]signed
2
-32768..32767
0..65535
(entfällt)
[un]signed int
4
2147483648..214748 0..4294967295
3647
(entfällt)
[un]signed long
8
-2^63..2^63-1
0..2^64-1
(entfällt)
float
4
(entfällt)
+/- 3.4E +/- 38
7
double
8
(entfällt)
+/- 1.7E +/- 308
15
10
(entfällt)
+/- 1.7E +/- 4932
19
short (int)
(int)
long double
4.2.6
Bit-Operatoren
Eine spezielle Variante der Operationen sind die Bit-Operationen, die eine Zahl bitweise in ihrer
Binärdarstellung verändern:
Operator
Int
<<
X
>>
Float Operation
Beispiel
Ergebnis
Linksschieben (Multiplikation mit Potenzen
von 2)
3<<2
12
X
Rechtsschieben (Division durch Potenzen
von 2)
16>>1
8
&
X
Bitweises UND
6&3
2
|
X
Bitweises ODER
9|3
11
^
X
Bitweises XOR (entweder-oder / exklusives
ODER)
7^5
2
~
X
Bitweises NOT (Negation)
~43
Je nach
Typ
3D26E882-2673-8602.doc/05.07.02/dr.b.
12
4.2.7
Logische Operatoren
Die nächste Klasse an Operatoren sind die logischen Operatoren. Dabei werden Integerzahlen
als wahrer Wert interpretiert, wenn sie ungleich Null sind, als falscher Wert sonst. Das
Ergebnis ist 1 falls wahr, 0 falls falsch. Auch hier ist eine Anwendung auf Fließkommazahlen
möglich, aber nicht sinnvoll.
Operator Int Float Operation
Beispiel
Ergebnis
&&
X
Logisches UND
i&&j
1, wenn i und j ungleich 0, 0 sonst
||
X
Logisches ODER
a||b
0 wenn a und b gleich 0, 1 sonst
!
X
Logisches NOT
(Negation)
!q
1 wenn q gleich 0, 0 sonst
Da logische Werte in C++ nichts anderes sind als Integerzahlen, kann man mit ihnen auch
rechnen. Dabei kann man z.B. folgenden Trick nutzen:
a = 5 + !!b * 7;
Dieser Ausdruck weist a den Wert 5 oder 12 zu, je nachdem ob b Null ist oder nicht
(falls b nicht Null, ist !b Null und !0 ist 1). Man sollte sich allerdings im klaren darüber sein,
daß solche Tricks der Lesbarkeit des Programms schaden.
Auch ist es wichtig, immer zwischen den bitweisen und den logischen Operatoren zu
unterscheiden. Besonders die beiden UND und ODER werden sehr leicht verwechselt, was
besonders schlimm sein kann, wenn es eine Zeitlang richtig funktioniert. Das kann nämlich dann
passieren, wenn Wahrheitswerte wirklich nur durch 0 und 1 dargestellt werden. Dann
unterscheiden sich die bitweisen und die logischen Operationen nicht. Doch sobald andere Werte
genutzt werden, treten Fehler auf, die im Nachhinein sehr schwer zu finden sein können.
3D26E882-2673-8602.doc/05.07.02/dr.b.
13
4.2.8
Relationale Operatoren
Die relationalen Operatoren führen Vergleiche durch und ergeben wie die logischen Operatoren
Wahrheitswerte, d.h. 0 oder 1.
Operator Int Float
Operation
Beispiel
Ergebnis
<
X
X
Vergleich auf kleiner
x<y
1, wenn x kleiner y, 0 sonst
>
X
X
Vergleich auf größer
y>x
1, wenn x größer y, 0 sonst
<=
X
X
Vergleich auf kleiner
oder gleich
x<=y
1, wenn x kleiner oder gleich y, 0
sonst
>=
X
X
Vergleich auf größer
oder gleich
y>=x
Wie bei x<=y
==
X
X
Prüfung auf Gleichheit
x==y
1, wenn x und y gleich, 0 sonst
!=
X
X
Prüfung auf
Ungleichheit
X!=43
0 wenn x gleich 43, 1 sonst
ACHTUNG:
Auch hier ist Vorsicht geboten, da der Vergleichsoperator (==) leicht mit dem
Zuweisungsoperator (=) verwechselt wird. Letzterer ist fast immer „wahr“, da eine Zuweisung
den zugewiesenen Wert zurückgibt (d.h. eine Zuweisung ist dann „falsch“, wenn Null
zugewiesen wurde). Falls man also nur ein statt zweier Gleichheitszeichen verwendet, so wird
zum einen der Ausdruck nicht richtig ausgewertet, zum anderen können unerwünschte
Nebenwirkungen auftreten. Manchmal ist es aber durchaus sinnvoll, das Ergebnis einer
Zuweisung abzufragen, nämlich dann, wenn eine erfolglose Zuweisung Null zurückgibt.
3D26E882-2673-8602.doc/05.07.02/dr.b.
14
4.2.9
Einige mathematische Funktionen
Eigentlich nicht zu C++ selbst gehören die folgenden mathematischen Funktionen.
Um sie zu nutzen muß man folgende Zeile in ein Programm aufnehmen:
#include <math.h>
Danach stehen u.a. folgende Funktionen zur Verfügung (x steht dabei, falls nichts anderes
erwähnt für eine beliebige Integer- oder Gleitkommazahl):
sqrt(x) Berechnet die Quadratwurzel
Berechnet den Sinus
exp(x) Berechnet die Exponentialfunktion bzgl. e
log(x) Berechnet den natürlichen Logarithmus
abs(x) Berechnet den Betrag (nur für Integerzahlen)
fabs(x) Berechnet den Betrag (als double)
sin(x)
3D26E882-2673-8602.doc/05.07.02/dr.b.
15
4.3
Ein- und Ausgabe
4.3.1
Elementare Ein-/Ausgabe
Klassische Befehle aus der C+Programmierung sind
•
•
•
•
getchar()
- zum Einlesen eines Zeichens
putchar()
- zum Ausgaben eines Zeichens
scanf()
- zum formatierten Einlesen eines Zeichens
printf()
- zum formatierten Ausgaben eines Zeichens
Diese Funktionen befinden sich in der header-Datei <stdio.h>, die dementsprechend mit dem
Befehl
#include <stdio.h>
eingebunden werden müßten.
4.3.2
Stream-Technik
Die Stream-Technik ist die konsequente Anwendung der objektorientierten Programmierung
auf die Ein- und Ausgabe (siehe unten).
Die Ein- und Ausgabe wird in C++ mit Hilfe sogenannter Streams durchgeführt, wobei man sich
zur anfänglichen Erleichterung ruhig vorstellen darf, daß es sich wirklich um einen "Datenstrom"
handelt, in dem die zu bearbeitenden Zeichenfolgen "entlangfließen". Dieses Bild unterstützen
auch die beiden Operatoren, die man zum Ein- bzw. Ausgeben von Zeichenfolgen benötigt: Für
die Ausgabe benötigt man den "schreibe in"-Operator <<, der wie folgt benutzt werden kann:
cout << "Dies ist eine erste Ausgabe";
cout stellt dabei den Standard-Ausgabekanal dar, d.h. die Zeile
Dies ist eine erste Ausgabe
wird üblicherweise zu einer Ausgabe auf dem Bildschirm führen.
3D26E882-2673-8602.doc/05.07.02/dr.b.
16
Der Operator << suggeriert hierbei, daß etwas in Richtung der Pfeile geschrieben bzw. geshiftet
wird, d.h. der Stream wird nach cout geschoben und damit ausgegeben. Um auf die im
Folgenden angegebenen I/O-Elemente zugreifen zu können, ist es nötig, die Standard-StreamI/O-Bibliothek <iostream.h> in das Programm einzubinden:
#include <iostream.h> // I/O-Bibliothek wird eingebunden
Ein großer Vorteil der Stream-Technologie liegt darin, daß man die gleiche Form der Ausgabe
für verschiedene Datentypen nutzen kann, ohne explizit den Datentyp angeben zu müssen:
#include <iostream.h>
void main()
{
int k = 5 ;
char c = 'a';
double d = 3.1241;
cout << k;
cout << c;
cout << d;
}
//
//
//
//
//
//
Deklaration (und Definition) einer Integer-Variable
Deklaration einer Char-Variablen
Deklaration einer Double-Variablen
Integer-Ausgabe
Char-Ausgabe
Double-Ausgabe
Zudem ist es möglich, mehrere Ausgaben - auch Ausgabe verschiedener Typen aneinanderzureihen.:
int k = 5;
double d = 3.5;
cout << "Das Ergebnis von " << k << " plus " << d << " lautet " << k + d;
Das Ergebnis von 5 plus 3.5 lautet 8.5
Man beachte, daß der Operator << eine so niedrige Priorität besitzt, daß auf eine Klammerung
des Ausdrucks (k+d) verzichtet werden kann.
3D26E882-2673-8602.doc/05.07.02/dr.b.
17
4.3.3
Einfache Manipulatoren
In den vorhergehenden Beispielen wurden die entsprechenden Werte stets hintereinander in einer
Zeile ausgegeben, d.h. Formatierungsanweisungen wie etwa "neue Zeile" haben wir bisher noch
nicht kennengelernt. Dies soll nun nachgeholt werden. Hierfür wird ein neuer Begriff benötigt,
der des Manipulators. Am Ende der meisten Ausgabe-Anweisungen wird etwa der Operator
endl ausgegeben:
cout << "Erste Ausgabe mit eine Manipulator am Ende" << endl;
Der Name Manipulator kommt daher, daß derartige Objekte (auch Manipulatoren passen in die
objektorientierte Philosophie) Manipulationen am Stream durchführen. Der eben kennengelernte
Manipulator endl steht für "endline" und bewirkt zweierlei:
1. Er gibt ein Newline (Zeichen '\n') aus und
2. leert anschließend den Ausgabepuffer (d.h. schickt die Ausgabe auch wirklich ab!)
Für die Ausgabe stehen drei einfache Manipulatoren zur Verfügung:
Manipulator
flush
endl
ends
Bedeutung
Ausgabepuffer leeren
'\n' ausgeben und Ausgabepuffer leeren
'\O' ausgeben und Ausgabepuffer leeren
Mit diesen Operatoren ist man in der Lage, zumindest einfache Formatierungen in Form von
Zeilenumbrüchen vorzunehmen. Da man bei der Ausgabe von Strings den jeweiligen String in
Anführungszeichen anzugeben hat, steht man vor dem Problem, daß man z.B. nicht in der Lage
ist, das Anführungszeichen an sich auszugeben:
cout << " Hier soll ein Anführungszeichen " stehen " << endl; // FEHLER
!!!
Der übergebene String endet nämlich mit den zweiten Anführungszeichen, der Rest ist dann für
den Compiler nicht mehr korrekt zu interpretieren. Eine Lösung findet sich in den im folgenden
aufgelisteten Escape-Sequenzen, die es zudem erlauben, weitere Formatierungen bei der
Ausgabe vorzunehmen.
3D26E882-2673-8602.doc/05.07.02/dr.b.
18
4.3.4
Escape-Sequenzen
Anweisung
Abkürzung für
\a
alert
\b
backspace
\n
new line
\t
horizontal tab
\v
vertical tab
\'
single quotation mark
\"
double quotation mark
\\
backslash
\O
NUL
\ddd
character in octal notation
\xhh
character in hex notation
4.3.5
Bedeutung
Piepton
Löscht Zeichen links vom Cursor
Neue Zeile
Horizontaler Tabulatorensprung
Vertikaler Tabulatorensprung
Hochkomma
Anführungszeichen
Rückstrich
Beendet die Ausgabe von Zeichenfolgen
Zeichen in Oktalzahl ddd
Zeichen mit dem Wert in Hexadezimalzahl
Eingabe
Für die Eingabe steht der zum Ausgabeoperator genau entgegengerichtete Operator >> zur
Verfügung, der ein ähnlich einfaches und elegantes Einlesen ermöglicht:
#include <iostream.h>
main()
{
int int_wert;
double double_wert;
cout << " Bitte geben Sie einen Integer und einen Double-Wert ein: " << endl;
cin >> int_wert >> double_wert;
// Einlesen der Werte
cout << "Es wurden die Werte ( "
<< int_wert << ", "
<< double_wert << ") eingegeben."
<< endl;
return 0;
}
In dem Beispiel wird man zur Eingabe zweier Werte aufgefordert, wobei die Werte
verschiedenen Typs sein sollen. Die Eingabe an sich erfolgt über die Zeile
cin >> int_wert >> double_wert;
cin stellt dabei das Objekt dar, aus dem heraus etwas gelesen werden soll. Im Standardfall wird
dies die Tastatur sein.
3D26E882-2673-8602.doc/05.07.02/dr.b.
19
Bei der Eingabe der beiden Werte ist darauf zu achten, daß diese durch ein Whitespaces-Zeichen
voneinander getrennt sind; dies kann ein Leerzeichen, aber auch ein <Return> sein. Die gesamte
Eingabe ist jedoch auf jeden Fall mit <Return> abzuschließen.
Die Veranschaulichung durch den Operator kann analog zur Ausgabe erfolgen: Wieder wird in
Richtung der Pfeile geschrieben. Auch hier muß der Typ des Objektes, in das etwas geschrieben
werden soll, nicht explizit angegeben werden; er wird implizit aus der angegebenen Variable
ermittelt.
Allerdings sollte man folgendes beachten:
Entspricht der eingebene Typ nicht dem Typ, der erwartet wird, so wird die Eingabe nicht
korrekt abgeschlossen. Da dies nicht unbedingt zu einer Fehlermeldung führt (z.B. werden u.U.
bei einem erwarteten Integer und eingegebenem Double einfach die Nachkommastellen
abgeschnitten und das Programm wird ohne Meldung fortgeführt), können sich überraschende
Ergebnisse des Programms einstellen! Ein Programmierer sollte daher immer die Eingabe auf
ihre Korrektheit hin überprüfen.
Zur Beachtung:
Ein allgemeines Vorgehen ist z.B. die Abfrage einer Bedingung in einer while-Schleife.
Im folgenden Beispiel wird die Eingabe zeichenweise verarbeitet:
char C;
while (cin >> C)
// ...
Dabei ist zu bemerken, daß bei der Eingabe wirklich Zeichen für Zeichen eingelesen wird,
Strings, d.h. zu einer Worteinheit zusammengefaßte Zeichen, werden nicht als solche behandelt,
sondern in die einzelnen Zeichen "zerlegt".
Zudem werden Whitespace-Zeichen vom Eingabestrom nicht als eigenständige Zeichen
behandelt, sondern dienen nur zur Abgrenzung der eingelesenen Werte. Die Zeichenfolge
nix t oll e s
wird also als eine Folge von neun Zeichen verarbeitet:
'n','i','x','t','o','l','l','e','s'.
Will man Whitespaces-Zeichen als solche berücksichtigen, so sind die Elementfunktionen
get(), getline() bzw. read() zu verwenden.
3D26E882-2673-8602.doc/05.07.02/dr.b.
20
4.4
Einfache Rechenoperationen
4.4.1
Addition, Multiplikation, Division, Modulo-Operator
// Grundrechenarten
# include <iostream.h>
int main ()
{
int summe, differenz,nur_rest, produkt, quotient, a=21, b=4;
summe = 21+4;
differenz = a-b;
produkt = a*b;
quotient = a/b;
nur_rest = a%b;
cout
<<
<<
<<
<<
<<
// Ganzzahlige Division der Rest geht verloren
/* Modulo-Operator
liefert den Rest einer ganzzahligen Division */
"summe =
"differenz =
"produkt =
"quotient =
"nur_rest =
"
"
"
"
"
<<
<<
<<
<<
<<
summe << "\n"
differenz << "\n"
produkt << "\n"
quotient << "\n"
nur_rest << "\n"
;
/* Tastaturkürzel:
strg+c = kopieren
strg+v = einfügen
strg+x = ausschneiden
*/
return (0);
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
21
4.4.2
Division mit Gleitkommazahlen
// Division und Fließ- Gleitkommazahlen
# include <iostream.h>
int main ()
{
int div_1, a=21, b=4 ;
float div_2, div_3, div_4, div_5, c=21, d=4 ;
div_1 = a/b;
div_2 = 7.26;
div_3 = a/b;
div_4 =21.0/4;
div_5 =c/d;
cout << "div_1
<< "div_2
<< "div_3
<< "div_4
<< "div_5
;
//
//
//
//
//
=
=
=
=
=
"
"
"
"
"
// Zelle die Fließkommazahlen
// speichern kann
ganzzahlige Division, Abspeicherung in int-Zelle
OK.
Ergebnis der ganzzahligen Division (5) wird in der
float- Zelle abgespeichert
Bei gemischten Zahlen nimmt der PC die genauere
<<
<<
<<
<<
<<
div_1
div_2
div_3
div_4
div_5
<<
<<
<<
<<
<<
"\n"
"\n"
"\n"
"\n"
"\n"
return (0);
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
22
4.4.3
Inkrement-Operator
// Inkrement
# include <iostream.h>
int main ()
{
int a, b, c=5, d, e, f, i=1, j=1, k=1, x=100, y=200 ;
i= i+1;
a= ++j;
// Erhöhung einer Variablen um 1
/* ++(j)=präfix-Inkrement Operator, zuerst wird j
inkrementiert
und danach wird der neue Wert nach a übergeben
Inkrement Operator=Erhöhungsoperator
*/
/* (k)++=postfix-Inkrement Operator, zuerst wird k in b
abgespeichert und danach erst wird k inkrementiert
*/
/* nur c wird inkrementiert
=> Ursprung des Namens C++
*/
//Präfix-Dekrement
//Postfix-Dekrement
b= k++;
c++;
--x;
y--;
cout << "i=
<< "a=
<< "b=
<< "k=
<< "c=
<< "x=
<< "y=
;
return (0);
}
"
"
"
"
"
"
"
<<
<<
<<
<<
<<
<<
<<
i
a
b
k
c
x
y
<<"\n"
<<"\n"
<<"\n"
<<"\n"
<<"\n"
<<"\n"
<<"\n"
// z.B. zum Hochzählen bei Schleifenrückläufen
3D26E882-2673-8602.doc/05.07.02/dr.b.
23
4.5
Schleifen und Bedingungen
4.5.1
Struktogrammelemente für C++
Die if-Anweisung
true
if (Ausdruck)
Anweisung(en) 1
false
Anweisung(en) 2
Die switch-Anweisung
switch (Ausdruck)
case 1
case 2
Anweisung(en) 1
Anweisung(en) 2
case n
Anweisung(en) n
default
Anweisung(en)
Die for-Anweisung
for (Initialisierung; Bedingung; Inkrement)
Anweisung(en)
3D26E882-2673-8602.doc/05.07.02/dr.b.
24
Die while-Anweisung
while (Ausdruck)
Anweisung(en)
Die do-while-Anweisung
Anweisung(en)
do ... while (Ausdruck)
3D26E882-2673-8602.doc/05.07.02/dr.b.
25
4.5.2
While-Schleife
// while-Schleife
/* Schleifenanweisungen
Zur wiederholten Ausführung von Programmteilen
stehen 3 Schleifenanweisungen zur Verfügung:
- while-Schleife
- do...while-schleife
- for-Schleife
Die Zahl der Schleifendurchläufe ist abhängig
von einem Parameter (Laufvariable), deren Wert
bei jedem Durchlauf der Schleife überprüft wird
(Bedingung erfüllt ja/nein).
*/
// hier: 5malige Textausgabe
#include <iostream.h>
int main()
{
int i=1;
// i = Laufvariable
while(i<=1)
// while(Bedingung erfüllt)
{
cout << i << ". Moin, moin!\n";
i++;
}
return(0);
}
/*
1. Darauf achten, daß die Bedingung mindestens 1mal
erfüllt wird, ansonsten wird dieser Programteil
übersprungen.
2. Auf jeden Fall das Inkrement so wählen, daß die
Bedingung irgend wann mal nicht erfüllt ist,
sonst Endlosschleife!!!!
3. Bei der while-Schleife ist die Bedingungsüberprüfung
am Anfang der Schleife.
*/
3D26E882-2673-8602.doc/05.07.02/dr.b.
26
4.5.3
Do...while-Schleife
// do...while-Schleife
// hier: Runterzählen von 10 auf 4
#include <iostream.h>
int main()
{
int i=10;
do
{
}
// i = Laufvariable
// Eintauchen in die Schleife
cout << i << "\n";
i--;
while(i>=4);
return(0);
}
/* Die Bedingungsüberprüfung ist am Ende der Schleife
und daher wird die Schleife mindestens 1mal
durchlaufen. */
3D26E882-2673-8602.doc/05.07.02/dr.b.
27
4.5.4
Switch-Anweisung
// Zahlenreihe
#include <iostream.h>
#include <iomanip.h>
int main()
{
int fall;
float xnminus1, xnminus2, xn;
cout.setf(ios::right | ios::fixed);
cout.precision(1);
cout << "Bitte eingeben:\n"
<< "1 = for-Schleife\n"
<< "2 = do...while-Schleife\n"
<< "3 = while-Schleife\n";
cin >> fall;
cout << "\n";
switch (fall)
{
case 1:
//*****
for-Schleife
*****
xnminus1=2.5;
xnminus2=1.5;
cout << setw(5) << xnminus2 << "\n";
for (xn=2.5; xn<1000; )
{
cout << setw(5) << xn << "\n";
xn = xnminus1 + 2*xnminus2;
xnminus2=xnminus1;
xnminus1= xn;
}
break;
case 2:
//*****
do...while-Schleife
*****
xnminus1=2.5;
xnminus2=1.5;
cout << setw(5) << xnminus2 << "\n";
xn=2.5;
do
{
cout << setw(5) << xn << "\n";
xn = xnminus1 + 2*xnminus2;
xnminus2=xnminus1;
xnminus1= xn;
}
while (xn<1000);
break;
case 3:
//*****
while-Schleife
xnminus1=2.5;
xnminus2=1.5;
3D26E882-2673-8602.doc/05.07.02/dr.b.
*****
28
cout << setw(5) << xnminus2 << "\n";
xn=2.5;
while (xn<1000)
{
cout << setw(5) << xn << "\n";
xn = xnminus1 + 2*xnminus2;
xnminus2=xnminus1;
xnminus1= xn;
}
break;
default:
cout << "Falscher Eingabewert!";
}
return (0);
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
29
4.5.5
Musteraufgabe „Fahrenheit“
Schreiben Sie ein C++-Programm zur Umrechnung der Temperaturen von
Celsius in Fahrenheit.
Verwenden Sie die Umrechnungsformel FAHREN = 1.8*CELSIUS+32.0.
Es soll folgende Tabelle auf dem Bildschirm ausgegeben werden:
ZEILE
CELSIUS
FAHRENHEIT
-------------------------------1
2
3
.
.
.
11
20
22
24
68.0
71.6
75.2
40
104.0
Lösung mit einfacher Ausgabeformatierung
// Temperaturumwandlung ohne Ausgabeformatierung
#include <iostream.h>
int main()
{
int zeile=1, celsius;
float fahrenheit;
cout << "ZEILE
CELSIUS
FAHRENHEIT\n";
cout << "-----------------------------------\n";
do
{
celsius
= 18 + 2*zeile;
fahrenheit = 1.8*celsius + 32;
cout << zeile
<< "
<< celsius
<< "
<< fahrenheit << "\n";
zeile++;
} while (zeile<=11);
"
"
return(0);
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
30
Lösung mit objektorientierten Formatierungselementen
// Temperaturumwandlung mit Ausgabeformatierung
#include <iostream.h>
#include <iomanip.h>
int main()
{
int zeile=1, celsius;
float fahrenheit;
cout << "ZEILE
CELSIUS
FAHRENHEIT\n";
cout << "12345678901234567890123456789012345\n";
do
{
celsius
= 18 + 2*zeile;
fahrenheit = 1.8*celsius + 32;
cout.setf(ios::fixed | ios::right);
cout.precision(2);
/* . und :: sind Operatoren der
objektorientierten Programmierung */
cout << setw(5)
<< zeile
<< setw(14)
<< celsius
<< setw(16)
<< fahrenheit << "\n";
zeile++;
} while (zeile<=11);
return(0);
}
/* iomanip.h ermöglicht Ausgabeformatierungen:
setw(zahl)
= Vorschub des Cursors um zahl Stellen
right
= rechtsbündig
fixed
= feste Nachkommastellenzahl
precision(zahl) = Anzahl der Nachkommastellen
*/
3D26E882-2673-8602.doc/05.07.02/dr.b.
31
4.5.6
For-Scheife
Vollständige Syntax
// for-Schleife
/* Vollständige Syntax:
for(Initialisierung; Bedingung; Inkrement) Anweisung;
*/
#include <iostream.h>
int main()
{
int zahl;
for(zahl=1; zahl<=5; zahl++) cout << zahl << "\n";
return(0);
}
/*
1. Bei nur 1 Anweisung in der Schleife kann der
Verbundoperator {} entfallen.
2. Das Inkrement wird erst nach Abarbeitung
der Schleifnbefehle durchgeführt.
*/
Verkürzte Syntax
// for-Schleife mit Leeranweisungen
#include <iostream.h>
int main()
{
int zahl=4;
for( ; zahl<=5; )
{
cout << zahl << "\n";
zahl++;
}
return(0);
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
// Initialwert hier bereits
// Inkrement jetzt innerhalb der Schleife
32
Verschachtelte Schleifen
// Verschachtelte Schleifen
#include <iostream.h>
#include <iomanip.h>
int main()
{
int zahl=1, otto;
for(; zahl<=3;)
{
cout << zahl << ". Run\n";
for(otto=1; otto<=4; otto++)
{
cout << setw(4+2*otto) << otto << ". OTTO\n";
}
zahl++;
}
return(0);
}
/* Anstelle von festen Werten können an den
gleichen Stellen auch die Berechngsformeln
für die Werte stehen */
3D26E882-2673-8602.doc/05.07.02/dr.b.
33
4.5.7
If-Anweisung
// IF-Anweisung
#include <iostream.h>
int main()
{
int zahl;
cout << "Bitte Zahl eingeben: "; cin >> zahl;
if(zahl==5)
// Abfrage auf logisch TRUE
{
cout << "Die Zahl lautet fünf!\n";
// ggf. weitere Anweisungen
}
else
{
cout << "Die Zahl ist NICHT fünf!\n";
}
cout << "Ende des Programms.";
return(0);
}
/*
IF reicht aus, wenn bei Bedingung nur 1 Sache
abzuarbeiten ist.
IF .. ElSE, wenn zwischen 2 Alternativen
auszuwählen ist.
*/
3D26E882-2673-8602.doc/05.07.02/dr.b.
34
4.5.8
Boolsche Variablen
// Boolsche Variablen
/* Operator
C++-Symbol
AND
&&
OR
||
NOT
!
Beispiel
A&&B
A||B
!A
Eine NOT-Anweisung liefert TRUE,
wenn der zu testende Ausdruck FALSE ist
Beispiel:
if(!(x==5)) ist nur TRUE, wenn x ungleich 5 ist.
alt.: if(x!=5)
ad-hoc-Aufgabe: Programmieren Sie eine der NORVerknüpfungszeilen
Für Zuhause: Formatierte Tabelle für
die Äquivalenz-Verknüpfung mittels Schleifenoder if-Anweisung programmieren
*/
#include <iostream.h>
int main()
{
bool A, B, X, Z=1;
do
{
cout << "A = "; cin >> A;
cout << "B = "; cin >> B;
X = !(A||B);
// Verknüpfung wird berechnet
cout << "X = " << X << "\n";
cout << "Neuer Run? 0=nein, 1=ja: ";
cin >> Z;
} while (Z==1);
cout << "Programmende.\n";
return(0);
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
35
4.5.9
Zeichen- und Zeichenketten
// Zeichen und Zeichenketten (String)
#include <iostream.h>
int main()
{
char einzeichen = 'X';
char z1 = 65,
z2 = 90;
// 1 Byte lang
char MeinName[6] = "BUSSE";
// Zeichen im ASCII-Code
// 65 ... 90 => Großbuchstaben des Alphabets
// String
/* Min. Feldlänge gleich
Textlänge zzgl. 1Byte */
cout << einzeichen
<< z1
<< z2
<< MeinName
;
return(0);
}
// hier keine eckigen Klammern
<<
<<
<<
<<
"\n"
"\n"
"\n"
"\n"
3D26E882-2673-8602.doc/05.07.02/dr.b.
36
4.5.10
Einlesen von Tastaturzeichen
#include <iostream.h>
#include <conio.h>
int main()
{
char zeichen1;
cout << "Der PC wartet auf eine Tastatureingabe!\n";
zeichen1 = getch();
cout << " Danke! ... und nochmals!\n";
getch();
cout << "Danke, das war`s.";
cout << "Die erste Eingabe war das Zeichen "
<< zeichen1
<< "\nDas zweite Zeichen verrate ich nicht!\n";
return 0;
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
37
4.5.11
Kleine Musteraufgabe „Pole Position“
Vier HWI-Professoren sollen auf dem Bildschirm leicht versetzt namentlich eine Startaufstellung
wie beim Formel-1-Rennen bilden.
Lösung:
// Programm Pole Position
#include <iostream.h>
#include <iomanip.h>
int main()
{
char formel_1_pilot[4][10]
= {
"EWE",
"BUSSE",
"ROEBEN",
"ORLOWSKI"};
int i;
cout << "Die Startreichenfolge ist:\n\n";
for (i=0; i<4; i++)
{
cout << "\t" << formel_1_pilot[i] << "\n";
i++;
cout << "\t\t" << formel_1_pilot[i] << "\n";
}
return(0);
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
38
4.5.12
Goto-Anweisung
// goto-Anweisung
#include <iostream.h>
int main()
{
int i;
anfang:
// Sprungmarke setzen (Label)
cout << "Bitte die Zahl 1 oder 2 eingeben: ";
cin >> i;
if (i==1) goto anfang;
// Bedingter Sprung nach "anfang"
goto ende;
cout << "Hey, ich werde dauernd übersprungen!";
ende:
cout << "Ich bin jetzt am Ende.\n";
return(0);
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
39
4.5.13
Chaotische Programmierung
// goto-Anweisung
#include <iostream.h>
int main()
{
int i;
anfang:
// Sprungmarke setzen (Label)
cout << "Bitte die Zahl 1 oder 2 eingeben: ";
cin >> i;
if (i==1) goto anfang;
// Bedingter Sprung nach "anfang"
goto ende;
mitte:
cout << "Hey, ich bin jetzt auch mal dran!\n";
goto GanzZumSchluss;
ende:
cout << "Ich bin jetzt am Ende.\n";
goto mitte;
GanzZumSchluss:
cout << "Tschüss... ";
return(0);
}
/* Diesen Programmierstiel möglichst vermeiden!!!
besser:
* Schleifenbefehle verwenden
* Unterprogramme (Funktionen) schreiben */
3D26E882-2673-8602.doc/05.07.02/dr.b.
40
4.5.14
Switch-Anweisung
// switch-Anweisung zur Fallunterscheidung
#include <iostream.h>
int main()
{
int zahl;
cout << "Bitte 1, 2 oder 3 eingeben: ";
cin >> zahl;
switch (zahl)
{
case 1: cout <<
break;
case 2: cout <<
break;
case 3: cout <<
break;
default: cout <<
}
"Ich habe eine EINS eingegeben.\n";
"Ich habe eine ZWEI eingegeben.\n";
"Ich habe eine DREI eingegeben.\n";
"Die Zahl war nicht 1, 2 oder 3!\n";
cout << "Programmende.";
return(0);
}
// break ist auch in Schleifen anwendbar
3D26E882-2673-8602.doc/05.07.02/dr.b.
41
4.5.15
Musteraufgabe „PIN“
Einlesen einer PIN
// PIN-Eingabe
#include <iostream.h>
#include <conio.h>
// für getch() erforderlich
int main()
{
char pin1='1', pin2='2', pin3='7', pin4='8';
char e1, e2, e3, e4;
neueEingabe:
cout << "Bitte Geheimzahl eingeben: ";
e1 = getch();
/* Einlesen eines Tastaturzeichens
ohne Bildschirmausgabe (ohne Echodruck) */
cout << "*";
e2 = getch();
cout << "*";
e3 = getch();
cout << "*";
e4 = getch();
cout << "*";
if ((pin1!=e1) || (pin2!=e2) || (pin3!=e3) || (pin4!=e4))
{cout << "\nFalsche Geheimzahl\n";
goto neueEingabe;}
cout << "\nProgrammende.";
return(0);
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
42
4.6
Unterprogramme
// Unterprogramme (Funktionen)
// hier: Flächenberechnung
#include <iostream.h>
int berechnung(int, int); /*Funktionsdeklaration
= Funktionsprototy
der Rückgabewert ist vom
Typ int, die vom Hauptprogramm
übergebenen Wete sind ebenfalls
vom Typ int*/
//*****************************Hauptprogramm
int main()
{
int x=4, y=7, flaeche;
flaeche = berechnung(x, y); /* x- und y-Werte werden
an das Unterprogramm mit
dem Namen berechnung
übergeben, der Ergebniswert
der Berechnung wird in die
Speicherzelle flaeche
eingespeichert */
cout << flaeche;
return(0);
}
//**********************************************
// Unterprogramm
// Funktionsdefinition
int berechnung(a,b) // a,b sind sog. lokale Variable
{
int ergebnis;
ergebnis = a*b;
return (ergebnis);
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
43
4.7
Datenfelder (Arrays)
4.7.1
Eindimensionale Arrays
// Datenfelder
// bekannt: Textfeld
char MeinName[20] = "Hans im Glück";
/*
Datenfeld = Array (strukturierte Anordnung von Daten)
= Gruppe von Speicherzellen für Daten
desselben Typs, z.B. int, float
=> Daten haben den gleichen Variablennamen
und erhalten zur Unterscheidung einen Laufindex
| 22 | 04 | 12 | 83 |
0
1
2
3
hier: 4 Speicherzellen vom Typ int
Zählnummer für die i-te Zelle
Die einzelnen Zellen heißen Elemente des Arrays,
also hier Array mit 4 Elementen.
beachten: der Laufindex beginnt bei 0!!!
bei nur einem Laufindex handelt es sich um ein
eindimensionales Array.
*/
// Deklaration
typ feldname[feldgroesse];
// z.B.
int MeinErstesDatenfeld[4];
float hans[24];
// hier: Elemente vom Typ float
// Definition (= Initialisierung)
// a) einzeln
MeinErstesDatenfeld[0] = 22;
MeinErstesDatenfeld[1] = 4;
// usw.
// b) sofort bei Deklaration, bekannt int x=5;
int MeinErstesDatenfeld[4] = {22, 4, 12, 83};
// c) über Formel o.ä.
for (i=0; i<= 5; i++)
{
MeinZweitesDatenfeld[i] = 7*i + 48;
}
// es wird in MeinZweitesDatenfeld[0] der Wert 48 eingesp., usw.
// Zugreifen auf das i-te Element
int x, i=2;
x = MeinErstesDatenfeld[2];
// x = 12
/* Vorteil:
Die einzelnen Elemente lassen sich über eine
Laufvariable (z.B. in einer Schleife)
leicht ansprechen */
3D26E882-2673-8602.doc/05.07.02/dr.b.
44
4.7.2
Mehrdimensionale Arrays
/* Mehrdimensionale Arrays
| 22 | 04 | 12 | 83 |
| 23 | 06 | 17 | 99 |
| 11 | 02 | 01 | 83 |
0
1
2
3 =>
*/
0
1 => Laufindex für Zeile
2
Laufindex für Spalte
int feldname[zeilenzahl][spaltenzahl];
// hier:
int otto[3][4];
// Zugriff:
int y;
y = otto[2][0];
// y = 11
Beispiel
// Programm 52array.cpp
#include <iostream.h>
int main()
{
// Beispiel eindimensionales Array
int i=0, claudia[6];
for (; i<=5; i++)
{
claudia[i] = 7*i + 48;
cout << claudia[i] << "\n";
}
// Beispiel mehrdimensionales Array
int x=0, y=0;
int richard[3][5] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
// Zeilenweises Auffüllen der Elemente des Arrays
for (; x<=2; x++)
{
for (; y<=4; y++)
{
cout << richard[x][y] << " ";
}
y=0;
cout << "\n";
}
return(0);
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
45
4.7.3
Musteraufgabe „Schachbrett“
Aufgabe und Lösungsansatz
/*
Programm
Reiskörner auf Schachfeld, Anzahl verdoppelt sich jeweils
Am Ende soll die Körnerzahl des 20. Feldes nochmals ausgegeben werden
Lösung:
- verwenden Sie ein 2-dim. Array
- vorteilhaft ist die exp-Fkt.
Syntax:
double ergebnis = pow(double basis, double exponent)
*/
// Vorlüberlegung, probieren Sie:
#include <iostream.h>
#include <math.h>
int main()
{
double ergebnis, k=10;
ergebnis = pow(2, k);
cout << "2 hoch 10 = " << ergebnis;
return(0);
}
/* Tips
double brett[8][8];
mit i, j = Laufvariablen für beide Richtungen
von 0 ... 7 in 2 verschachtelten Schleifen
*/
3D26E882-2673-8602.doc/05.07.02/dr.b.
46
Lösung:
// Reiskörner auf einem Schachbrett
#include <iostream.h>
#include <math.h>
int main()
{
int i=0, j=0;
double k=0;
// Laufvariable für Potenzierung
double Brett[8][8];
char z=65;
for (;i<8;i++)
{
for (;j<8;j++)
{
Brett[i][j] = pow(2, k);
k++;
cout <<k <<"\t" <<z <<j+1 <<"\t" << Brett[i][j] << "\n";
}
j=0;
z++;
cout << "\n";
}
cout <<"\nDas 20. Feld (3. Reihe, 4. Spalte) enthält " << Brett[2][3] <<"
Reiskörner.\n";
return 0;
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
47
5
Objektorientierte Programmierung
5.1
Methodischer Ansatz
5.1.1
Typen
Menschen kategorisieren, d.h. sie klassifizieren, ordnen, gruppieren, unterteilen, usw.
=> Wir denken in Typen von Dingen. Typen besitzen ähnliche Merkmale.
Typen sind aus der C++-Programmierung bereits bekannt, z.B. die Variablentypen wie
int x;
//
x ist vom Typ integer.
Damit ist festgelegt:
• Speicherplatzgröße
• Speicherbare Information
• die mit der Variablen ausführbaren Aktionen.
Standardtypen wie int heißen Basisklassen.
Ein Programmierer kann sich eigene Typen erzeugen. Jeder neu definierte Type kann über die
gesamte Funktionalität der vordefinierten Typen verfügen.
5.1.2
Klassen und Elemente
Einen neuen Typ erzeugt man durch die Definition einer Klasse. Eine Klasse ist eine Sammlung
von Variablen kombiniert mit einer Gruppe verwandter Funktionen und Fähigkeiten.
5.1.3
Klassen deklarieren
Um eine Klasse zu deklarieren, verwendet man das Schlüsselwort class, gefolgt vom Namen
und den Datenelemeten in {}.
class Katze
{
int alter;
int gewicht;
miauen();
};
3D26E882-2673-8602.doc/05.07.02/dr.b.
48
Diese Deklaration belegt noch keinen Speicherplatz für eine Katze. Sie ist eine Anweisung an
den Compiler, was die Klasse der Katzen darstellt, welche Daten sie enthält und was sie kann.
Der Compiler muß in diesem Beispiel für eine bestimmte Katze zwei Integer-Bereiche für Alter
und Gewicht reservieren, aber keinen Bereich fürs Miauen, da es sich hierbei um eine
Elementfunktion = Methode handelt, die keinen Speicherplatz benötigt.
5.1.4
Objekte definieren
Katze Josie, FritzTheCat;
Josie ist ein Objekt der Klasse / des Typs Katze. Mit dieser Anweisung wird ein konkretes
Objekt der Klasse Katze definiert und dem Objekt der Name Josie zugewiesen.
5.1.5
Auf Klassenelemente zugreifen
Josie ist ein Objekt vom Typ Katze. Mithilfe des Punktoperators (.) kann man auf die Elemente
des Objekts zugreifen.
Allg. Syntax:
Objektname.Variablennamen oder Objektname.Methode
Josie.gewicht = 4;
// es wird der Wert 4 kg an die Elementvariable gewicht
des Objekts Josie zugewiesen
FritzTheCat.miauen();
5.1.6
// Aufrufen der Funktion Miauen
Definition einer Elementfunktion
Elementfunktionen sind zu definieren.
Allg. Form:
Klassenname::Methodenname(Parameter)
Beispiel:
Katze::miauen()
{
cout << "Miauuuuuuu.\n"
}
Die Elementfunktion hat das Aussehen eines Unterprogramms, das bei Aufruf abgearbeitet wird.
3D26E882-2673-8602.doc/05.07.02/dr.b.
49
5.2
Musteraufgabe „Katzendatei“
// OOP Katzenprogramm
#include <iostream.h>
// Deklaration eines eigenen Typs ************************
class katzen // hier alle Eigenschaften aller Katzen aufgeführt
{
public:
// das gesamte Programm kann nachstehendes nutzen
float gewicht;
char name[10];
miauen();
eingabe();
ausgabe();
};
// Semikolon nicht vergessen
// METHODENDEFINITION ************************************
katzen::miauen()
{
cout << "\n
...Miauuuu... man hat mir auf den Schwanz getreten!!!\n";
}
katzen::eingabe()
{
cout << "Name:
cout << "Gewicht:
cout << "\n";
}
"; cin >> name;
"; cin >> gewicht;
katzen::ausgabe()
{
cout << "Die Katze mit Namen\t" << name
<< "\twiegt\t"
<< gewicht
<< " kg und schreit:";
}
// HAUPTPROGRAMM
int main()
{
katzen katze[3];
int i;
*****************************************
// es gibt konkret 3 europäische Kauskatzen
for(i=0; i<=2; i++) {katze[i].eingabe();}
for(i=0; i<=2; i++) {katze[i].ausgabe();
katze[i].miauen();}
return(0);
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
50
3D26E882-2673-8602.doc/05.07.02/dr.b.
51
6
Assembler-Programmierung
// Beispiel Assembler-Routinen
#include <iostream.h>
int main()
{
int multiplikant, multiplikator, produkt;
cout << "Multiplikant eingeben: "; cin >> multiplikant;
cout << "Multiplikator eingeben: "; cin >> multiplikator;
// in Assembler multiplizieren:
// Ladebefehl für ein Register: mov ZIEL, QUELLE
_asm
{
/* 32-Bit Akkumulatorregister eax (Vielzweckregister)
ax = untere 16-bit von eax */
mov ax, multiplikant
/* Der Ram-Speicher-Inhalt von
multiplikant wird in den unteren
Teil des eax-Registers eingspeichert*/
mov bx, multiplikator
/* weiteres Vielzweckregister*/
mul bx
/* bx wird mit ax multipliziert
und in ax abgespeichert*/
mov produkt, ax
/* auslagern des Rechenergebnisses
nach produkt*/
}
cout << "\n"
<< " * "
<< " = "
return 0;
}
<< multiplikant
<< multiplikator
<< produkt;
3D26E882-2673-8602.doc/05.07.02/dr.b.
52
7
Mathematische Methoden
7.1
Musteraufgabe „Sortieren“
// Sortieren nach dem Bubblesort-Algorithmus
#include <iostream.h>
int main()
{
int i, j, k, hilf, merke, a[]={7,3,1,5};
for (i=0; i<=3; i++) cout << "a[" << i << "] = " << a[i] << "\n";
cout << "\n";
// Minimales Element im verbleibenden Intervalls suchen
for(i=0; i<3; i++)
{ merke = i;
// Schleife über alle noch nicht sortierten Elemente
// Vermerke aktuelles Element als bisher kleinstes
for(j=i+1; j<4; j++)
{
if(a[j] < a[merke]) merke = j;
// a[merke] ist das kleinste Element
}
// i-tes Element mit dem minimalen vertauschen
hilf
= a[i];
a[i]
= a[merke];
a[merke] = hilf;
for (k=0; k<=3; k++) cout << "a[" << k << "] = " << a[k] << "\n";
cout << "\n";
}
cout << "\n";
for (i=0; i<=3; i++) cout << "a[" << i << "] = " << a[i] << "\n";
return (0);
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
53
8
Weitere Beispielaufgaben
8.1
Musteraufgabe „Bruchkürzen“
Schreiben Sie ein C++-Programm zum Kürzen von Brüchen.
Es sind der Zähler und der Nenner eines Bruches ganzzahlig einzulesen. Der so definierte Bruch
ist durch den größten gemeinsamen Teiler (ggT) von Zähler und Nenner zu kürzen, so daß ein
nicht weiter kürzbarer neuer Bruch entsteht. Z.B.
Zähler: 30
Nenner: 5
Ausgabe:
30
---5
6
= ---1
Das Hauptprogramm soll nur die Funktionsaufrufe
Eingabe();
Kuerze();
Ausgabe();
enthalten. Schreiben Sie die Funktionen eingabe, kuerze und ausgabe mit den notwendigen
Übergabeparametern sowie das Gesamtprogramm.
3D26E882-2673-8602.doc/05.07.02/dr.b.
54
Lösung
// Programm Bruchkuerzen
#include <iostream.h>
#include <iomanip.h>
int z1,z2,n1,n2;
// Globale Variable
int eingabe()
{
cout << "Eingabe des Zählers:
cin >> z1;
cout << "Eingabe des Nenners:
cin >> n1;
cout << "\n\n\n";
return (0);
}
";
";
int kuerzen()
{
int ggt, ggt_max;
if (z1>=n1) ggt_max=n1;
else ggt_max=z1;
for (ggt=1; ggt<=ggt_max; ggt++)
{
if ((z1%ggt==0) && (n1%ggt==0))
{z2=z1/ggt; n2=n1/ggt;}
}
return (0);
}
int ausgabe()
{
cout << setw(8) << z1 << setw(10) << z2 << "\n";
cout << "
----- = -----\n";
cout << setw(8) << n1 << setw(10) << n2;
return (0);
}
// Hauptprogramm***********************
int main()
{
eingabe();
kuerzen();
ausgabe();
return 0;
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
55
8.2
Musteraufgabe „Geldautomat“
Es soll ein Geldautomat simuliert werden, der folgende Scheine ausgeben kann:
1000er-, 500er-, 200er-, 100er-, 50er-, 20er- und 10er-Scheine.
Wie bei einem echten Geldautomaten soll zunächst eine vierstellige Geheimzahl (PIN) abgefragt
werden. Bei der Eingabe der vier Ziffern darf jeweils nur ein ´*´ auf dem Bildschirm erscheinen
und nicht die eingegebene Ziffer.
Wird die Geheimzahl dreimal falsch eingegeben, so bricht das Programm mit einer
entsprechenden Meldung ab.
Bei richtiger Geheimzahl kann dann der gewünschte Betrag eingegeben werden.
Ist der Betrag nicht durch 10 teilbar, erfolgt ein entsprechender Hinweis mit der Möglichkeit der
nochmaligen Eingabe des gewünschten Betrages.
Im Programm soll berechnet werden, wie der Betrag mit möglichst wenigen Scheinen
ausgegeben werden kann. Als Nachweis erscheint ein Ausgabebeleg auf dem Bildschirm, z.B.
bei 740 DM: 1 Fünfhunderter, 1 Zweihunderter, 2 Zwanziger.
Entwickeln Sie für die Aufgabe zunächst ein Struktogramm und schreiben Sie dann ein
ablauffähiges C++-Programm.
Hinweis:
Verwenden Sie vorzugsweise die Header-Dateien iostream.h, iomanip.h und conio.h.
Letztere unterstützt das Einlesen von Tastaturzeichen ohne Echo auf dem Bildschirm durch
Verwendung der Anweisung getch(). Beispiel:
char g1;
g1=getch(); /* Einlesen eines Tastaturzeichens ohne Ausgabe auf dem Bildschirm und
Übergabe in die Speicherzelle g1. */
// g1 kann dann mit der entsprechenden PIN-Ziffer logisch auf Identität verglichen werden.
3D26E882-2673-8602.doc/05.07.02/dr.b.
56
Lösung:
// Programm Geldautomat
#include <iostream.h>
#include <iomanip.h>
#include <conio.h>
// Deklaration der verwendeten Funktionen
void geheimzahl();
int betragseingabe();
void berechnung(int betrag);
// Hauptprogramm ****************************
int main()
{
geheimzahl();
int betrag=betragseingabe();
berechnung(betrag);
return(0);
}
// *******************************************
void geheimzahl()
{
char pin1='1'; char pin2='2'; char pin3='3'; char pin4='4';
char g1, g2, g3, g4;
neueEingabe:
cout << "Bitte geben Sie Ihre Geheimzahl ein: ";
g1=getch();
cout << "*";
g2=getch();
cout << "*";
g3=getch();
cout << "*";
g4=getch();
cout << "*";
if ((g1!=pin1) || (g2!=pin2) || (g3!=pin3) || (g4!=pin4))
{
cout << "\nDie Geheimzahl ist falsch!\n";
goto neueEingabe;
}
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
57
int betragseingabe()
{
neueEingabe:
// Sprungmarke für goto-Befehl
cout << "\nBitte geben Sie den auszuzahlenden Betrag an: ";
int betrag;
cin >> betrag;
if ((betrag%10)!=0)
{
cout << "Der Betrag muß durch 10 teilbar sein!!!\n\n";
goto neueEingabe;
// Gehe zur Sprungmarke neueEingabe
}
return (betrag);
}
void berechnung(int betrag)
{
int array[] = {1000, 500, 200, 100, 50, 20, 10};
int i;
cout << "Sie erhalten:\n";
for (i=0;i<=7;i++)
{
int anzahl = betrag/array[i];
betrag = betrag - anzahl*array[i];
if (anzahl != 0) cout << setw(2) << anzahl << setw(6) << array[i]
<< "-Mark-Schein(e)\n";
}
}
3D26E882-2673-8602.doc/05.07.02/dr.b.
58
Zugehörige Unterlagen
Herunterladen