Einsteig in die Programmierung mit Cpp

Transcrição

Einsteig in die Programmierung mit Cpp
C++
Vorwort
Dieses Skript befindet sich noch unter Bearbeitung sowie unter Korrektur.
Gruß Konstantin Rink.
©Konstantin Rink
1|Seite
C++
Inhalt
BEVOR ES LOS GEHT.
4
1.0 WIE AUS EINEM QUELLCODE EIN AUSFÜHRBARES PROGRAMM WIRD
5
2.0 SYNTAXDIAGRAMME
7
2.1 NASSI-SHNEIDERMAN-DIAGRAMM
10
2.1.1 DER LINEARE ABLAUF
2.1.2 KONTROLLSTRUKTUREN(VERZWEIGUNGEN)
EINFACHE AUSWAHL (IF-ABFRAGE)
MEHRFACH AUSWAHL (IF-ELSE-ABFRAGE)
VERSCHACHTELTE AUSWAHL
FALLAUSWAHL (WIRD MEIST BEI SWITCH-CASE VERWENDET)
2.1.3 WIEDERHOLUNGEN (SCHLEIFEN)
KOPFGESTEUERTE SCHLEIFE
FUßGESTEUERTE SCHLEIFE
ENDLOSSCHLEIFE
SCHLEIFE MIT AUSTRITTSBEDINGUNG
AUSSPRUNG (BREAK)
10
10
10
11
11
11
12
12
12
12
12
12
3.0 SOFTWARE EINRICHTEN
14
3.1 ERSTER START
17
4.0 DER ALLGEMEINE AUFBAU EINES C++ PROGRAMMES
18
DER INCLUDE-BEFEHL
19
AUSGABE
20
ZEILENUMBRÜCHE
22
VARIABLEN
23
DER TYP
DER NAME
DER WERT
DEKLARATION UND INITIALISIERUNG VON VARIABLEN
GELTUNGSBEREICH VON VARIABLEN
23
24
24
25
25
KONSTANTE
27
ZEIGER/POINTER
28
OPERATOREN
29
©Konstantin Rink
2|Seite
C++
DIE EINGABE IN C++
31
ABSCHLIEßEND MÖCHTEN WIR UNS NOCH DEN EINGABEWERT, ALSO DEN WERT DER VARIABLE
ZAHL AM BILDSCHIRM MITHILFE VON COUT AUSGEBEN LASSEN (Z. 11).KONTROLLSTRUKTUREN 31
KONTROLLSTRUKTUREN
32
DIE WENN DANN (IF/ELSE)-FUNKTION
DIE ELSE IF FUNKTION
DIE SWITCH AND CASE FUNKTION
32
33
34
MATHEMATISCHE FUNKTIONEN
36
SCHLEIFEN
37
DIE WHILE-SCHLEIFE
DIE FOR-SCHLEIFE
DIE DO-WHILE-SCHLEIFE
EINE SCHLEIFE VORZEITIG ABBRECHEN/PROZEDUR IN EINER SCHLEIFE ÜBERSPRINGEN
WANN VERWENDE ICH WELCHE SCHLEIFE?
38
39
40
41
42
EINDIMENSIONALE FELDER (ARRAYS)
43
D EFINITION UND INITIALISIERUNG VON EINDIMENSIONALEN ARRAYS
EINLESEN /AUSGEBEN VON EINDIMENSIONALEN ARRAYINHALTEN MIT SCHLEIFEN
EINEN BESTIMMTEN WERT VON EINEM ARRAY AUSGEBEN
43
44
46
MEHRDIMENSIONALE ARRAYS
47
EINLESEN /AUSGEBEN VON MEHRDIMENSIONALEN ARRAYINHALTEN MIT SCHLEIFEN
EINEN BESTIMMTEN WERT VON EINEM MEHRDIMENSIONALEN ARRAY AUSGEBEN
48
49
BUBBLESORT UND DREIECKSTAUSCH
50
DREIECKSTAUSCH
BUBBLESORT
50
52
ARBEITEN MIT ARRAYS
54
LÖSUNGEN
55
FUNKTIONEN
57
RÜCKGABEWERT
CALL BY VALUE
CALL BY REFERENCE
59
60
62
©Konstantin Rink
3|Seite
C++
Bevor es los geht…
Möchte ich Sie über den Aufbau dieses Skripts und wie man am besten damit arbeitet informieren.
Wenn man möchte kann man dieses Skript in drei Teile aufteilen, in einen Teil indem Ihnen die
theoretischen Methoden der Programmierung näher gebracht werden, in einen Teil in dem Ihnen die
Syntax von einzelnen Befehlsfunktionen erklärt werden und in einen Übungsteil indem Sie das
Wissen aus den gelernten Befehlsfunktionen und Transferwissen anwenden.
Die einzelnen Kapitel sind so erstellt, dass man dieses Skript auch als Nachschlagwerk benutzen kann,
sofern man schon erste Erfahrungen mit der Programmiersprache gemacht hat.
Andernfalls sollte man die Kapitel in chronologischer Reihenfolge abarbeiten, denn die Kapitel
greifen ineinander über und setzten das dementsprechende Wissen aus dem vorherigen Kapitel
voraus.
©Konstantin Rink
4|Seite
C++
1.0 Wie aus einem Quellcode ein ausführbares
Programm wird
In C++ wenn man so möchte, gibt es drei Arten von Dateitypen mit denen wir arbeiten werden.
Standartbibliothekdateien:
In C++ gibt es die sog. Standardbibliothek, in ihr befinden sich Headerdateien in denen unsere
Standartfunktionen deklariert sind. Um diese Headerdateien in unsere Hauptdatei einbinden zu
können, verwenden wir den include-Befehl (Kapitel XX).
Headerdateien:
Neben den Headerdateien in der Standartbibliothek unseres Compilers hat man die Möglichkeit auch
eigene Headerdateien zu schreiben um beispielsweise eigene Funktionen zu deklarieren.
Normale Quelldateien:
In dieser Datei schreiben wir unser eigentliches Programm. Diese Quelldatei bindet mithilfe des
include-Befehls die Headerdateien ein und kann so auf die deklarierten Funktionen zugreifen.
Um aus unseren Quelldateien bzw. unserem geschriebenen Quelltext ein ausführbares Programm zu
machen, werden noch einige Schritte durchlaufen.
Zuerst tritt der sogenannte Präprozessor in Kraft, dieser hat zum einen die Aufgabe die Head-Dateien
die in den #include-Befehlen der .cpp-Dateien stehen, einzufügen (Abbildung 1). Zum anderen
werden noch weitere Aufgaben erfüllt wie Kommentare durch Leerzeichen zu ersetzen.
iostream
#include
#include
z.B. math.h
#include
Präprozessor
int main()
XYZ.cpp
XYZ.cpp
Abbildung 1
©Konstantin Rink
5|Seite
C++
Als zweites übernimmt der Compiler, dessen Aufgabe es ist ausschließlich die C++-Quelldateien(an
den Headerdateien ist er nicht interessiert, diese sind schon vom Präprozessor inkludiert worden) in
Objektdateien zu übersetzen(Abbildung 2). Diese enthalten eine Sprache die schon relativ der
Maschinensprache ähnelt. Wird zum Beispiel in der main-Funktion eine Funktion aus der C++-Datei
XYZ aufgerufen so steht an dieser Stelle ein Platzhalter für diese Funktion(Abbildung 3).
int main()
XYZ.cpp
XYZ.cpp
Compiler
Platzhalter
XXXXX für
Funktion aus
anderer Datei
.cpp Datei
int main(){
…
fkt123();
…
…
…
}
Abbildung 2
.o Datei
main:
…
jmp XXXXX
…
…
weitere
Platzhalter
Ersetzen durch
Platzhalter
Abbildung 3
Im letzten Schritt ist es die Aufgabe des sog. Linkers diese Platzhalter aufzulösen, er verbindet (eng.
to link) diese Dateien quasi zusammen(Abbildung 4). Als Endergebnis hat man dann eine ausführbare
Datei.
Linker
Abbildung 4
©Konstantin Rink
6|Seite
C++
2.0 Syntaxdiagramme
Das Syntaxdiagramm ist eine Methode um eine Regelmenge grafisch darzustellen. In einem Beispiel
möchten wir eine Regel für eine Zahl aufstellen, welche vorher festgelegte Werte enthalten darf.
Jedes Syntaxdiagramm wird von links nach rechts gelesen, aus diesem Grund müssen wir auch keine
Pfeilsymbole oder ähnliches verwenden.
Als erste Regel möchten wir festlegen, dass die Werte von 1-6 vorkommen dürfen:
1….6
Umgesetzt würde das bedeuten unsere Zahl darf einen Wert von 1-6 annehmen.
Zum Beispiel hat unsere Zahl dann den Wert 3.
Nun möchten wir, dass die Werte von 1-6 auch mehrfach vorkommen dürfen.
1….6
Jetzt kann unsere Zahl beliebig viele Werte im Bereich von 1 bis 6 annehmen, entweder nur eine Zahl
mit einem Durchlauf oder auch 2,3,4,n-stellige Zahlen im Wertebereich von 1-6 da man jetzt die
Möglichkeit hat, mehrere Durchläufe zu starten.
Im nächsten Schritt möchte ich aus meiner einfachen Zahl gerne eine Gleitkommazahl machen, also
benötigte ich ein Komma bzw. im englischen und auch in C++ verwendet man anstatt eines Kommas
einen Punkt. Zudem sind wir die ganze Zeit nur von positiven Werten ausgegangen, eine Zahl kann
auch ein negatives Vorzeichen haben, aus diesem Grund möchten wir das noch zusätzlich mit
realisieren.
1….6
.
Jetzt kann unsere Gleitkommazahl negative Werte annehmen oder positive.
©Konstantin Rink
7|Seite
C++
Was uns jetzt noch in diesem Beispiel fehlt sind die Nachkommastellen, denn momentan ist es nur
möglich vor dem Komma Werte anzunehmen zudem ist es noch nicht möglich Werte wie 0.2
anzunehmen.
1….6
.
.
1-6
1-6
Betrachten wir nun das Syntaxdiagramm.
Unsere Zahl kann ein negatives Vorzeichen annehmen, beliebig viele Werte zwischen 1 und 6
annehmen und Nachkommastellen haben oder auch keine.
Die Zahl kann auch erst mit einem Komma und beliebig vielen Nachkommastellen beginnen.
Dies ist selbstverständlich nur eine Schreibweise von vielen, es wäre auch möglich, das gleiche
Vorhaben in einem ähnlichen Syntaxdiagramm zu realisieren.
Nach diesem Beispiel als Einleitung gewöhnen wir uns ein paar Fachbegriffe für den späteren
Gebrauch an.
In dem obigen Beispiel haben wir ovale Symbole verwendet, im Syntaxdiagramm nennt man diese
auch terminale Symbole.
Neben den terminalen Symbolen gibt es auch noch non-terminale/nicht-terminale Symbole. Diese
drückt man grafisch mit einem Viereck aus.
Um den Unterschied zwischen terminalen und non-terminalen Symbolen aufzuzeigen, hier ein
einfaches Beispiel:
Farben
rot
blau
gelb
„Farben“ ist in diesem Beispiel die Wortgruppe also ein non-terminales Symbol(=es lässt sich weiter
unterteilen) und die einzelnen Wörter (rot, blau, gelb) stellen die endgültigen (terminierten) Symbole
da, diese lassen sich nicht weiter unterteilen.
Unbewusst haben wir im obigen Beispiel schon einige Grammatikregeln angewandt, nun möchten
wir diesen auch noch Namen geben.
Folgen mehrere non-terminale aufeinander so nennt man dies eine Sequenz.
Syntaxdiagramm zu einer Sequenz:
A
©Konstantin Rink
B
C
8|Seite
C++
Möchte man eine Auswahl haben ob man A mit B oder mit C verbindet nennt man dies eine
Alternative.
Syntaxdiagramm zu einer Alternative:
B
A
C
Möchte man, dass sich eine oder mehrere non-terminale wiederholen, nennt man dies eine
Iteration(zu Deutsch Wiederholung).
Diese unterscheidet man noch einmal in eine rückläufige(rekursive) Wiederholung und in eine
iterative Wiederholung.
Syntaxdiagramm zu einer iterativen Wiederholung:
A
B
Syntaxdiagramm zu einer iterativen rückläufigen Wiederholung:
A
B
A
In dem Fall einer iterativen rückläufigen Wiederholung ist es wie man sieht möglich, das A den Wert
B annehmen kann oder nicht. Möchten wir aber, dass es diese Möglichkeit nicht gibt und nach dem A
den Wert B annimmt wiederholend den Wert A annimmt dann sprechen wir von einer (normalen)
Rekursion.
Syntaxdiagramm zu einer Rekursion:
A
B
A
Wie man hier nun erkennen kann, nimmt A erst die Werte von B mit an und danach
nochmals/wiederholend von A.
©Konstantin Rink
9|Seite
C++
2.1 Nassi-Shneiderman-Diagramm
Bevor wir ein Programm schreiben, müssen wir uns überlegen, welche Funktionen unser Programm
haben bzw. ausführen soll. Da evtl. wir nicht direkt mit der Programmierung später beschäftigt sein
werden, bzw. mehrere Personen an diesem Projekt arbeiten, bräuchten wir also eine Art Norm die
uns hilft anderen Personen die Vorgehensweise unseres Programmes näher zu bringen. Eine
Möglichkeit ist ein Struktogramm.
Mithilfe des Nassi-Shneiderman-Diagramms setzen wir die Vorgehensweise grafisch und ohne eine
Programmiersprache zu verwenden um. Der Vorteil ist, dass mithilfe dieses Struktogrammes unser
Programm von Dritten verstanden werden kann, ohne dass diese eine Programmiersprache
beherrschen müssen. Ein weiterer Vorteil ist, dadurch dass keine Programmiersprache in diesem
Struktogramm verwendet wird, können Programmierer unser Programm auch in anderen
Programmiersprachen z.B. in Java umsetzen.
Dieses Kapitel greift jetzt vorab auf Funktionen zurück die in C++ existieren, aus diesem Grund würde
ich Sie bitten, dieses Kapitel als Nachschlagwerk zu verwenden. Wenn Sie später an einem Kapitel
angekommen sind, z.B. bei Kontrollstrukturen können Sie die gewünschte grafische Vorgehensweiße
nachschlagen.
2.1.1Der lineare Ablauf
Anweisungen(z.B. Initialisierung von Variablen) werden in sog. rechteckige Strukturblöcke
geschrieben. Dabei ist zu beachten, dass diese Blöcke nicht neben sondern immer untereinander
geschrieben werden. Das Struktogramm wird immer von Oben nach Unten gelesen.
Anweisung 1
Initialisierung
Funktionsaufruf
2.1.2 Kontrollstrukturen(Verzweigungen)
Einfache Auswahl (If-Abfrage)
Bedingung
Trifft zu
Anweisung 1
©Konstantin Rink
Trifft nicht zu
Trifft die oben festgelegte Bedingung
zu (true) wird Anweisung 1
ausgeführt, ist dies nicht der Fall
(false) wird nichts ausgeführt.
10 | S e i t e
C++
Mehrfach Auswahl (If-Else-Abfrage)
Bedingung
true
false
Anweisung 1
Anweisung 2
Trifft die oben festgelegte Bedingung
zu (true) wird Anweisung 1
ausgeführt, ist dies nicht der Fall
(false) wird Anweisung 2 ausgeführt.
Verschachtelte Auswahl
Es kann vorkommen, dass wenn beispielsweiße eine Bedingung false sein sollte, eine weitere
Auswahl ausgeführt werden soll anstatt einer Anweisung.
Bedingung
true
false
Bedingung
Anweisung 1
true
Anweisung2
false
Anweisung3
Trifft die oben festgelegte Bedingung
zu (true) wird Anweisung 1
ausgeführt, ist dies nicht der Fall
(false) wird eine weitere Bedingung
geprüft, trifft diese zu (true) wird
Anweisung2 ausgeführt, trifft diese
nicht zu (false) wird Anweisung3
ausgeführt.
Fallauswahl (wird meist bei Switch-Case verwendet)
Variable
Bedingung1
Bedingung2
Anweisung1
Anweisung2
Bedingung3
Anweisung3
Bedingung n
Anweisung n
ansonsten
Alternat.
Anweisung
Eine Variable wird auf verschiedene Bedingungen geprüft, trifft eine dieser
Bedingungen zu, wird eine Anweisung ausgeführt, optional kann man auch
festlegen, wenn keine der Bedingungen zutrifft (ansonsten) wird eine
Anweisung ausgeführt.
©Konstantin Rink
11 | S e i t e
C++
2.1.3 Wiederholungen (Schleifen)
Kopfgesteuerte Schleife
Diese Wiederholung bzw. nennen
wir sie Schleife, führt solange die
Anweisung aus, bis die Bedingung
false ist.
Bedingung
Anweisung
Anweisung
Fußgesteuerte Schleife
Bei dieser Schleife wird die
Bedingung erst nach Ausführung der
Anweisung geprüft. Aus diesem
Grund wird die Anweisung
mindestens einmal ausgeführt ehe
die Bedingung false ist.
Anweisung
Bedingung
Endlosschleife
Endlosschleife, das sollte Ihnen nicht
passieren, es sei denn es ist explizit
von Ihnen gewünscht.
Anweisung
Schleife mit Austrittsbedingung
Bedingung
Anweisung
Bedingung
True
false
Diese Schleife hat eine
Austrittsbedingung, ist die
Austrittsbedingung true wird die
Schleife beendet, ansonsten werden
die Anweisungen weiter ausgeführt.
Anweisung
Aussprung (break)
©Konstantin Rink
Falls Sie sich einen Punkt weiter
oben gefragt haben, was dieses
Objekt hier bedeutet, hier die
Antwort: Es wird verwendet um den
Aussprung (break;) zu realisieren.
12 | S e i t e
C++
Abschließend möchte ich an einem Beispiel die Umsetzung eines Nassi-Shneidermann-Diagrammes
in einen C++ Quellcode zeigen. Die Bezeichnung der einzelnen Blöcke steht frei, ich empfehle aber
überwiegend Pseudocode zu verwenden bzw. klar verständliche Formulierungen.
Als Struktogramm
Zahl: INTEGER
i: INTEGER
Daten[5] :INTEGER := 1,2,3,4,5
Eingabeaufforderung :=Zahl
Zähle i von 0 bis 5, Erhöhung pro Durchlauf +1
Bedingung
True
False
„Die Zahl ist dabei“
Umgesetzt in C++
©Konstantin Rink
13 | S e i t e
C++
3.0 Software einrichten
Bevor wir nun jetzt zum praktischen Teil dieses Skripts übergehen und beginnen zu programmieren
müssen wir vorher noch einen Editor in dem wir C++ schreiben und einen Compiler mit dem wir den
Quellcode in eine ausführbare Datei umwandeln installieren.
Da sich dieses Skript ausschließlich mit dem Einstieg in die Programmierung beschäftigt ist es nicht
zwingend notwendig Programme zu verwenden mit denen man meist größere Projekte realisiert.
Aus diesem Grund empfehle und verwende ich das Programm Dev++ da es neben dem Editor einen
Compiler integriert hat.
Installation
Die Installation erfolgt einfach und ist in XX Schritte unterteilt:
Schritt 1
Zu Beginn bekommen wir einen Hinweis indem wir gebeten werden andere bereits installierte
Versionen dieses Programmes nicht mit der aktuellen Installation zu überschreiben. Wir bestätigen
mit einem Klick auf den OK-Button um fortzufahren.
Schritt 2
Im nächsten Schritt wählen wir die Sprache Deutsch aus und fahren fort.
©Konstantin Rink
14 | S e i t e
C++
Schritt 3
Wir bestätigen das Lizenzabkommen indem wir auf den Annehmen-Button klicken.
Schritt 4
In diesem Schritt können wir den Installations-Typ bestimmen. Ich empfehle „Full“ zu selektieren und
mit „Weiter“ forzufahren.
©Konstantin Rink
15 | S e i t e
C++
Schritt 5
Im letzten Schritt vor der Installation bestimmen wir das Zielverzeichnis unseres Programmes. Mit
dem Klick auf „Installieren“ wird die Installation von Dev-C++ durchgeführt.
Schritt 6
Nachdem Dev-C++ erfolgreich installiert wurde klickt man auf „Fertig stellen“ um die Installation
abzuschließen und den Editor zu starten.
©Konstantin Rink
16 | S e i t e
C++
3.1 Erster Start
Bei jedem Start des Programmes werden wir zur Begrüßung mit dem „Tip des Tages“ empfangen.
Diese Tipps sind für Anfänger, die sich mit dem Editor näher beschäftigen wollen bzw. Shortcuts und
Kniffe erlernen möchten nicht schlecht. Durch einen Klick auf das Kästchen unterhalb der Nachricht
kann man diese Begrüßungen jedoch deaktivieren.
Durch einen Klick auf den Menüpunkt Datei >Neu>Quelldatei[1] oder durch den Shortcut STRG+N
öffnen wir eine neue Quelldatei in der wir unser erstes Programm schreiben können[2].
Zur Sicherheit sollten Sie die Quelldatei speichern indem Sie entweder im Menü auf Datei>Speichern
unter gehen oder kurz STRG+S auf Ihrer Tastatur drücken.
Abb. 1
©Konstantin Rink
Abb. 2
17 | S e i t e
C++
4.0 Der Allgemeine Aufbau eines C++
Programmes
Bevor ich Ihnen nun erkläre wie wir in unserem Editor eine Quelldatei kompilieren kommen wir nun
zum allgemeinen Aufbau eines Programmes bzw. einer Quelldatei in C++.
Bevor wir die einzelnen Begrifflichkeiten und Ausdrücke klären, vorne weg hier ein Quellcodeauszug
zu dem Standardaufbau.
Auf den ersten Blick mag der Quellcode etwas kryptisch und unverständlich aussehen, jedoch ist ein
sehr logisches und festes System dahinter.
Jeder Quellcode beginnt mit einem Einfügen/Inkludieren einer Datei. (Z. 1) Dies geschieht mit dem
include-Befehl, die genaue Syntax von diesem Befehl wird in einem Kapitel weiter erklärt.
Dieser Befehl fügt, wie man sieht, eine Datei namens iostream ein. In dieser Datei sind Funktionen
(wie z.B. Kontrollstrukturen, Schleifen, etc.) definiert die wir später beim Programmieren benötigen.
Aus diesem Grund ist es wichtig, dass diese Datei als erstes in jedem unserer Quellcodes inkludiert
wird.
Der nächste Befehl der uns ins Auge sticht ist in Zeile 2 „using namespace std;“
Dieser Befehl wird uns das Programmieren etwas schöner gestalten. Um auf eine Funktion
zuzugreifen, sei es z.B. der Befehl für die Bildschirmausgabe, macht man dies über ihren namespace,
zu Deutsch Namensraum. Im Kapitel mit der Bildschirmausgabe und unserem ersten „Hallo Welt“,
werde ich noch einmal darauf zurück kommen und anhand eines Beispiels zeigen was genau der
Vorteil ist.
Nun haben wir quasi den Kopf unseres Quellcodes besprochen und kommen nun zur Hauptfunktion,
der main()-Funktion.
Diese Funktion ist der Einstiegspunkt unseres Programmes, das bedeutet, dass wenn wir später mit
anderen Funktionen außerhalb der main()-Funktion arbeiten, die Befehle die später in unserer
main()-Funktion stehen immer als erstes ausgeführt werden. Möchte man eine Funktion später
aufrufen/ausführen muss dies immer über die main()-Funktion geschehen, da es anders keinen Sinn
macht.
Innerhalb der geschweiften Klammern werden wir in den kommenden Kapiteln unsere ersten
Befehle schreiben. Wichtig ist auf die genaue Syntax zu achten. Würden wir beispielsweise in Zeile 11
die geschweifte Klammer weglassen, würden wir einen Fehler von unserem Compiler erhalten.
©Konstantin Rink
18 | S e i t e
C++
Der include-Befehl
Include-Befehle stehen immer in den ersten Zeilen unseres Quellcodes, schließlich würde es wenig
Sinn machen eine Funktion aus einer Datei aufrufen zu wollen die wir erst viel weiter unten in
unserem Quellcode inkludieren.
Syntax:
#include <dateiname(.h)>
Hier muss man beachten, und aus diesem Grund auch das (.h), ob es sich um eine Header-Datei aus
der Programmbibliothek handelt(z.B. iostream) oder um eine Header-Datei die wir selbst erstellt
haben.
Handelt es sich um eine Datei aus der Programmbibliothek so lässt man das .h weg, handelt es sich
um eine eigene bzw. eine die nicht aus der Programmbibliothek stammt, schreibt man diese mit .h.
Ein Beispiel hierzu:
©Konstantin Rink
19 | S e i t e
C++
Ausgabe
Nachdem wir uns mit dem Grundriss und dem Kopf eines C++ Programmes beschäftigt haben,
kommen wir nun zur main()-Funktion und zu unserem ersten Befehl, der Bildschirmausgabe.
Vorneweg hier der Quellcode:
Wie man erkennen kann, wird der Befehl cout verwendet danach folgen zwei Pfeilsymbole und in
Anführungszeichen unser Ausgabetext.
Als allgemeine Syntaxregel lässt es sich so darstellen:
Syntax:
cout << <Wert>;
Möchten wir Text auf dem Bildschirm ausgeben so schreibt man diesen in Anführungszeichen,
handelt es sich aber um Zahlen, Variablen oder Funktionen so verwendet man keine
Anführungszeichen.
Nun möchte ich wie in Kapitel XX besprochen auf den using namespace std; Befehl zurück kommen.
Wie schon erwähnt, benötigt man den Namensraum(namespace) um auf eine Funktion zuzugreifen
zu können. Würde ich diesen Befehl nicht verwenden, sähe unsere Syntax so aus:
Syntax:
std::cout << <Wert>;
Es ist Ihnen überlassen für welchen Weg Sie sich entscheiden, ich werde in diesem Skript using
namespace std; nutzen, damit ich mir jedes mal das „std::“ spare.
Möchte man mehrere Werte ausgeben, kann man dies realisieren indem man einfach zwei weitere
Pfeilsymbole verwendet und diese „anhängt“.
Syntax:
cout << <Wert> << <Wert2> << <Wert3>;
©Konstantin Rink
20 | S e i t e
C++
Nachdem wir nun ein Programm geschrieben haben welches uns etwas ausgibt und man somit etwas
am Bildschirm sehen kann, möchten wir nun unsere Quelldatei kompilieren und ausführen um zu
sehen ob alles geklappt hat.
Hierzu klicken wir auf das Fenstersymbol in der dritten Symbolleiste von oben [1]. Oder verwenden
den Shortcut F9.
Nun sollte für einen sehr kurzen Augenblick sich ein Fenster geöffnet und wieder geschlossen haben.
Um dieses Problem zu lösen, schließlich wollen wir ja gerne auch unser Ergebnis sehen, schreiben wir
ab jetzt immer den „system(„pause“)-Befehl“ an das Ende bzw. vor die geschweifte Klammer, jedes
von uns geschriebenen Quellcodes.
Umgesetzt sieht es so aus:
Drücken wir erneut das Fenstersymbol bzw. die F9-Taste wird das Fenster offen bleiben und wir
werden „Hallo Welt“ angezeigt bekommen.
Im Folgenden werden einige Beispiele der Bildschirmausgabe gezeigt:
Würden wir das Programm jetzt kompilieren und ausführen, würden wir die Bildschirmausgabe in
einer Zeile erhalten, bzw. er würde keine Zeilenumbrüche machen, da schließlich keine von uns im
Quelltext angeordnet wurden.
©Konstantin Rink
21 | S e i t e
C++
Zeilenumbrüche
Zeilenumbrüche kann man mit zwei Befehlen realisieren, zum einen durch „\n“ zum anderen durch
den Befehl endl;
Der Unterschied zwischen den Befehlen ist, dass bei dem endl-Befehl zusätzlich das alle
zwischengespeicherten Daten ausgegeben werden(Synchronisation) . Aus diesem Grund ist der endlBefehl auch aufwendiger/langsamer.
Möchten wir also unsere Sätze mit Zeilenumbruch ausgeben würde man es so realisieren:
©Konstantin Rink
22 | S e i t e
C++
Variablen
Bisher kennen wir Variablen nur aus der Mathematik, diese verwenden wir als Platzhalter (auch
Stellvertreter genannt), für einen Wert den wir errechnen oder in Abhängigkeit davon ausrechnen.
Um es relativ simpel zu halten, würde ich gerne das Wort „Platzhalter“ in „Behälter“ umtaufen.
Stellen wir uns also eine Variable in der Programmierung wie einen Behälter vor.
Der Behälter besitzt folgende Eigenschaften:
•
•
•
Einen Typ
Einen eindeutigen Namen
Einen Wert
Der Typ
Unser Programm wird später mit Werten arbeiten. Diese Werte werden vorübergehend in den
Arbeitsspeicher unseres Computers geschrieben um logischerweise mit ihnen schnell arbeiten zu
können. Da unser Arbeitsspeicher allerdings begrenzt ist, müssen wir angeben wie viel Speicher für
unsere Variable reserviert/frei gehalten werden soll.
In C++ unterscheidet man zwischen folgenden Typen:
Typ
Speicherplatz Wertebereich
Verwendung
bool
1 Byte
true, false
(signed) char
1 Byte
-128 bis +127
Kann den Wert 1 für true
und den Wert 0 für false
erhalten.
Wir für Zeichen(A,B,C,..)
verwendet.
unsigned char
(signed )int*
1 Byte
4 Byte
0 bis 255
-2.147.483.648 bis +2.147.483.647
unsigned int
4 Byte
0 bis 4.294.967.295
short int
long
unsigned long
float
4 Byte
4 Byte
4 Byte
4 Byte
-32.768 bis 32.767
-2.147.483.648 bis 2.147.483.647
0 bis 4.294.967.295
3,4E-38 bis 3,4E+38
(7 Nachkommastellen)
double
8 Byte
1,7E-308 bis 1,7E+308
(15 Nachkommastellen)
long double
10 Byte
3,4-4932 bis 1,1E+4932
*Die Größe ist Systemabhängig, wir gehen von einem 32Bit OS aus.
Ganzzahl mit Vorzeichen
(also auch negativen
Werte)
Ganzzahl ohne Vorzeichen
(also nur positive Werte)
Fließkommazahl
Fließkommazahl bei sehr
genauen Werten.
Fließkommazahl
Float oder Double wo sind die Unterschiede?
Wenn es wichtig ist, bei Berechnungen ein sehr genaues Ergebnis zu erzielen, verwendet man
double, da double, wie der Name schon sagt, die doppelte Genauigkeit hat wie float.
©Konstantin Rink
23 | S e i t e
C++
Der Name
C++ ist keysensitive, das bedeutet, dass C++ zwischen Groß- und Kleinschreibung unterscheidet.
Die Variable mit den Namen kleinerApfel ist nicht gleich die Variable kleinerapfel. Sprich für C++ sind
das zwei völlig verschiedene Variablennamen.
Zudem existieren Wörter bzw. Begriffe die schon von C++ aus vordefiniert sind und deswegen nicht
als Variablennamen verwendet werden dürfen. Folgende Wörter dürfen nicht verwendet werden:
and
bitand
case
compl
default
dynamic_cast
export
for
inline
namespace
operator
protected
return
static
template
try
union
void
xor
and_eq
bitor
catch
const
delete
else
extern
friend
int
new
or
public
short
static_cast
this
typedef
unsigned
volatile
xor_eq
asm
bool
char
const_cast
do
enum
false
goto
long
not
or_eq
register
signed
struct
throw
typeid
using
wchar_t
auto
break
class
continue
double
explicit
float
if
mutable
not_eq
private
reinterpret_cast
sizeof
switch
true
typename
virtual
while
Ansonsten ist Ihnen die Namenswahl frei überlassen. Bedenken Sie aber bitte, dass Sie Ihren
Variablen sinnvolle Namen geben sollten, um bei einem etwas größeren Quelltext nicht die Übersicht
zu verlieren.
Der Wert
Hier muss man auf keine großen Besonderheiten achten, außer natürlich, dass der Wert der
Variablen mit dem richtigen Datentyp deklariert ist.
Nachdem wir uns mit dem theoretischen Teil der Variablen befasst haben, kommen wir nun zum
praktischen Teil.
©Konstantin Rink
24 | S e i t e
C++
Syntax:
<Datentyp> <Variablenname> = <Wert der Variable>
Deklaration und Initialisierung von Variablen
Unter einer Deklaration einer Variablen versteht man, dass wir bestimmen von welchem Datentyp
unsere Variable ist. Von einer Initialisierung spricht man, wenn man einer Variablen einen Wert
zuweist. Dabei wird der Zuweisungsoperator „=“ verwendet.
Im Folgenden werden einige Beispiele und Möglichkeiten der Deklaration und Initialisierung von
Variablen gezeigt.
Geltungsbereich von Variablen
In dem bisherigen Beispiel wurden unsere Variablen innerhalb der main-Funktion deklariert und
initialisiert. Das bedeutet, und hier muss man leider vorgreifen, dass diese Variablen ihre Gültigkeit
nur in der main-Funktion haben. Möchten andere Funktionen mit dieser Variable arbeiten bzw. auf
den Wert der Variablen zugreifen könnte man dies nur durch eine Parameterübergabe realisieren.
Aus diesem Grund gibt es die Möglichkeit seine Variablen global zu deklarieren und initialisieren.
Ein Beispiel hierfür:
©Konstantin Rink
25 | S e i t e
C++
Zu Beachten ist, dass bei globalen Variablen die Deklaration und Initialisierung in einer Zeile erfolgen
muss, andere Schreibweisen sind nicht erlaubt.
Der Nachteil den globale Variablen haben ist, dass jede Funktion globale Variablen neu initialisieren
kann und somit die Werte von diesen ändern kann wie man in diesem Beispiel hier sieht:
Möchten wir eine Variable erstellen die einen konstanten Wert und ihre Gültigkeit den ganzen
Programmablauf über hat, verwenden wir sog. Konstante, dazu mehr im nächsten Kapitel.
©Konstantin Rink
26 | S e i t e
C++
Konstante
Syntax:
const <Datentyp> <Konstantenname> = <Wert der Konstanten>
Im folgenden Beispiel möchten wir nun eine lokale Konstante deklarieren und initialisieren und dabei
sehen, was passiert wenn wir dieser Konstanten später an irgendeiner Stelle im Quellcode einen
neuen Wert zuweisen möchten.
Selbstverständlich ist es auch möglich globale Konstanten zu erstellen wie man in diesem Beispiel
hier sieht:
©Konstantin Rink
27 | S e i t e
C++
Zeiger/Pointer
©Konstantin Rink
28 | S e i t e
C++
Operatoren
C++ stellt uns eine große Menge von Operatoren für die unterschiedlichsten Anwendungen zur
Verfügung. Auf diese möchten wir nun in diesem Kapitel eingehen.
Unbewusst haben wir schon 3 Operatoren verwendet, den Zuweisungsoperator („=“) um Variablen
zu initialisieren, den *Operator und den &-Operator für die Werteübergabe mit Zeigern.
Vorzeichen-Operatoren
- Minus
int zahl1= -5
Die Variable zahl1 erhält einen negativen Wert -5.
+ Plus
int zahl2 = -zahl1
int zahl3 = 5
Die Variable zahl2 erhält einen positiven Wert 5.
Die Variable zahl3 erhält einen positiven Wert 5.
int zahl4 = +zahl3
Die Variable zahl4 erhält einen Positiven Wert 5.
Arithmetische Operatoren
+ Addition
int zahl1= 3
int zahl2 = zahl1+4
- Subtraktion
* Multiplikation
/ Division
% Modulo
int zahl3 = 5
int zahl4 = zahl3-4
int zahl5 = 4
int zahl6 = zahl5*8
int zahl7 = 64
int zahl8 = zahl7/8;
int zahl9 = 10;
int zahl10 = zahl9%3
Dividiert die Werte seiner Operanden und gibt
den Rest zurück. Kann nur auf ganzzahlige
Operanden angewendet werden.
Vergleichs Operatoren
== Gleichheit
zahl1 == zahl2
Gibt true zurück, wenn beide Operanten gleich
sind, ansonsten false.
!= Ungleichheit
zahl3 != zahl4
<= kleiner oder
gleich
>= größer oder
gleich
< kleiner
zahl5<=zahl6
Gibt true zurück, wenn beide Operanten
ungleich sind, ansonsten false.
Gibt true zurück, wenn der Linke Operant kleiner
oder gleich dem Rechten ist, ansonsten false.
>größer
zahl11>zahl12
©Konstantin Rink
zahl7>=zahl8
Gibt true zurück, wenn der Linke Operant größer
oder gleich dem Rechten ist, ansonsten false.
zahl9<zahl10
Gibt true zurück, wenn der Linke Operant kleiner
als der Rechte ist.
Gibt true zurück, wenn der Linke Operant größer
als der Rechte ist.
29 | S e i t e
C++
Zuweisungs-Operatoren
++ Inkrement
zahl1=1;
zahl1++;
Erhöht den Wert des Operanten um 1.
-- Dekrement
zahl2=1;
zahl2--;
zahl5=3;
Vermindert den Wert des Operanten um 1
= Zuweisung
Weist den linken Operanten den Wert des
rechten Operanten zu.
Kombinierte Zuweisungsoperatoren
+=
-=
*=
/=
%=
©Konstantin Rink
zahl1+=zahl2
Der Linke Operant wird mit dem Rechten addiert.
Andere Schreibweise: zahl1= zahl1+zahl2
zahl3-=zahl4
Der Linke Operant wird mit dem Rechten subtrahiert.
Andere Schreibweise: zahl3=zahl3-zahl4
zahl5*=zahl6
Der Linke Operant wird mit dem Rechten
multipliziert.
Andere Schreibweise: zahl5=zahl5*zahl6.
zahl7/=zahl8
Der Linke Operant wird mit dem Rechten dividiert.
Andere Schreibweise: zahl7=zahl7/zahl8.
zahl9%=zahl10 Der Linke Operant wird mit dem Rechten dividiert
und es wird der Rest zurückgegeben.
Andere Schreibweise: zahl9=zahl9%zahl10.
30 | S e i t e
C++
Die Eingabe in C++
Nachdem wir jetzt alle notwendigen Voraussetzungen besitzen und bereits Werte am Bildschirm
ausgeben lassen können, kommen wir nun zur Eingabe von Werten.
Syntax:
cin >> <Variable>;
Dies geschieht wie man sieht sehr einfach mit dem Befehl cin. Ähnlich wie bei cout verwendet man
die Pfeilsymbole. Jedoch zeigen diese bei cin in die entgegengesetzte Richtung.
Man kann sich als Eselsbrücke merken, dass der Wert den der Benutzer eingeben soll, in der Variable
gespeichert wird, deswegen die Pfeilchen nach rechts.
Möchte man stattdessen einen Wert auf dem Bildschirm ausgeben lassen, wandern die Pfeile bei
cout nach links.
Im folgenden Quellcode möchten wir den Benutzer um eine Eingabe bitten. Der Wert der Eingabe
wird in einer Variablen gespeichert und soll am Bildschirm ausgegeben werden:
Erläuterung
Bevor wir uns an die Eingabeaufforderung wagen, deklarieren wir eine Variable in der der
Eingabewert gespeichert werden soll. (Zeile 7)
Damit der Benutzer dieses Programmes auch weiß, dass er etwas eingeben muss und nicht nur einen
blinkenden Cursor sieht, lassen wir zunächst mit cout am Bildschirm eine Eingabebitte ausgeben(Z.8).
Im Anschluss folgt der eigentliche Akt, hier wird der Eingabewert, in diesem Fall eine Ganzzahl in die
Variable zahl gespeichert (Z.9).
Abschließend möchten wir uns noch den Eingabewert, also den Wert der Variable zahl am Bildschirm
mithilfe von cout ausgeben lassen (Z. 11).
©Konstantin Rink
31 | S e i t e
C++
Kontrollstrukturen
Die Wenn Dann (if/else)-Funktion
Wenn Sie schon einmal mit Microsoft Excel Funktionen programmiert haben, kennen Sie sicherlich
die „wenn-Dann“-Funktion. Nichts anderes ist es in C++.
Syntax:
if(<Bedingung>){
< Ereignis1>;
}
else{
< Ereignis2>;
}
Ist die Bedingung erfüllt so wird das Ereignis1 ausgeführt, ist die Bedingung nicht erfüllt, so wird
Ereignis2 ausgeführt. Oder anders formuliert; wenn Bedingung erfüllt ist, dann führe Ereignis1 aus,
ansonsten führe Ereignis2 aus.
Ein simples Codebeispiel soll die Anwendung dieser Funktion erläutern:
Es sei noch gesagt, dass else nicht zwingend notwendig ist, sprich man kann auch den nur den if-Teil,
sofern erforderlich, verwenden.
Ein häufiger Leichtsinnsfehler der passiert ist, dass man den Zuweisungsoperator(„=“) mit dem
Vergleichsoperator(„==“) im Kopf der if-Funktion verwechselt, aus diesem Grund gilt hier
Aufmerksamkeit.
©Konstantin Rink
32 | S e i t e
C++
Die else if Funktion
Haben wir mehrere Ereignisse die zu unterschiedlichen Bedingungen ausgeführt werden, können wir
auf die else if-Funktion in C++ zurückgreifen, deren Syntax folgendermaßen aussieht:
Syntax:
if(<Bedingung>){
< Ereignis1>;
}
else if{
< Ereignis2>;
}
else if{
< Ereignis3>;
}
else if{
< Ereignis4>;
}
else{
<Ereignis n>;
}
Im folgenden Beispiel wird unsere Variable untersucht in welchem Wertebereich sie sich befindet.
Bildschirmausgabe in der Konsole:
Die Variable liegt im Wertebereich von 20 bis 30.
Drücken Sie eine beliebige Taste . . .
©Konstantin Rink
33 | S e i t e
C++
Die switch and case Funktion
-Too many ifs I think I switch ;-) -
Bisher haben wir größere Kontrollstrukturen immer nur mit der else if-Funktion realisiert. Jedoch
gestaltet sich das beispielsweise bei 30,100 Bedingungen als recht unpraktisch.
Aus diesem Grund gibt es in C++ die switch and case-Funktion. Diese erfüllt im Endeffekt denselben
Zweck wie die else if- Funktion.
Jedoch kommt es immer auf die individuelle Aufgaben-/Problemstellung an, denn man kann zum
Beispiel mit der switch and case-Funktion nicht überprüfen in welchem Wertebereich eine Variable
liegt.
Syntax:
switch(<Ausdruck auf den die Bedingungen geprüft werden sollen>){
case <Bedingung1>: <Ereignis1>; break;
case <Bedingung2>: <Ereignis2>; break;
case <Bedingung3>: <Ereignis3>; break;
case <Bedingung4>: <Ereignis4>; break;
case <Bedingung5>: <Ereignis5>; break;
}
Ein Codebeispiel soll uns Klarheit bringen:
In diesem Beispiel wird untersucht welchen Wert die Variable zahl besitzt.
Im Kopf der switch and case-Funktion tragen wir den Namen der zu prüfenden Variablen ein.
Im Schleifenkörper werden mit case beginnend die einzelnen Bedingungen geschrieben und mit
einem Doppelpunkt beendet. Danach folgt das Ereignis welches bei Eintreten der Bedingung
ausgeführt werden soll. Zuletzt wird nach jedem Ereignis der break-Befehl geschrieben.
Der Sinn des break-Befehls ist es, nachdem die Bedingung wahr und das Ereignis eingetreten ist, die
Kontrollstruktur zu verlassen. Geschieht dies nicht werden alle weiteren Ereignisse ausgeführt ohne
sie auf ihre Bedingung zu prüfen.
©Konstantin Rink
34 | S e i t e
C++
Bildschirmausgabe in der Konsole:
Die Variable liegt im Wertebereich von 20 bis 30.
Drücken Sie eine beliebige Taste . . .
Soll eine Bedingung eintreten, wenn keine der case-Bedingungen wahr (true) ist oder möchte man
eine Bedingung die in jedem Fall eintritt, so verwendet man den Befehl default. Der Befehl ist
optional und muss nicht zwingend in einer switch-Kontrollstruktur vorkommen.
Quellcodebeispiel:
Beachte:
In diesem Beispiel verwendet man den default-Befehl, wenn keine der Bedingungen wahr ist.
Aus diesem Grund steht er auch am Ende unserer Kontrollstruktur.
Möchten wir den default-Befehl aber dazu verwenden, dass er in jedem Fall eintritt, so kann man
diesen auch zu Beginn oder je nach Anforderung in die Mitte der Struktur schreiben.
Jedoch sollte man diesen dann nicht mit dem break-Befehl kombinieren, denn dann würde, sobald
der default-Befehl ausgeführt, ist die weiteren Überprüfungen abbrechen und die Kontrollstruktur
verlassen.
©Konstantin Rink
35 | S e i t e
C++
Mathematische Funktionen
In diesem Kapitel möchten wir uns kurz mit ein paar häufig benötigten mathematischen Funktionen
beschäftigen.
Es kann vorkommen, dass wir z.B. mit Potenzen, Wurzeln, Logarithmen, etc. rechnen müssen.
Aus diesem Grund gibt es die Datei math.h die wir zu Beginn unseres Quellcodes neben der
iostream-Datei inkludieren.
Im Folgenden nun Beispiel zu einigen Funktionen der math.h :
Wie schon erwähnt war dies nur ein sehr kurzer Ausschnitt aus der math.h eine ausführliche
Dokumentation finden Sie unter: http://www.cplusplus.com/reference/clibrary/cmath/
Da wir nun mit Variablen umgehen können und etwas von mathematischen Funktionen in C++ gehört
haben, kommen wir zu unserer ersten Aufgabe:
Aufgabe #1:
Der Benutzer soll eine quadratische Gleichung mithilfe unserer Anwendung lösen
können. Der Benutzer wird aufgefordert zuerst die Werte für a, b und c einzugeben, dann
soll mithilfe einer programmierten Mitternachtsformel (𝑥 =
entsprechende(n) Lösung(en) ausgegeben werden.
−𝑏±√𝑏 2 −4𝑎𝑐
2𝑎
) die
Hinweis:
a steht immer für x² und b für die x-Werte.
Um festzustellen wie viele Lösungen existieren berechnet man zuerst die Diskriminante
(b²-4ac) und wertet nach ihr aus.
Wer sich noch unsicher bei der Berechnung ist, sollte einen Blick in die Formelsammlung
wagen.
©Konstantin Rink
36 | S e i t e
C++
Schleifen
Wir werden in der Programmierung früher oder später an einen Punkt kommen, wo wir ohne
Schleifen nicht mehr weiter kommen. In der Programmierung versteht man unter Schleifen
Kontrollstrukturen, die einen Anweisungs-/Ereignisblock solange durchlaufen, bis ihre Laufbedingung
ungültig wird bzw. ihre Abbruchbedingung eintritt. Ist keine Laufbedingung gegeben bzw. tritt keine
Abbruchbedingung ein, so redet man von einer Endlosschleife.
Kurz gesagt, Schleifen wiederholen ein bestimmtes Ereignis bis sie ihre Gültigkeit verlieren oder sie
durch einen Befehl abgebrochen werden.
Man verwendet Schleifen also um eine Anzahl von bestimmten Ereignissen ausführen zu können. Vor
allem beim Arbeiten mit Arrays (Kapitel XX) finden Schleifen ihre Verwendung.
Hier die einzelnen Arten zur Verdeutlichung als Nassi-Shneiderman Diagramm:
Um aber möglichst praxisnah in das Thema eintauchen zu können hier eine Beispielaufgabe.
Folgende Aufgabenstellung zur Einleitung:
Der Benutzer soll eine Ganzzahl eingeben, der Wert der Zahl, z.B. 6 soll in Form von
Rauten am Bildschirm ausgegeben werden, in diesem Fall ######.
Insgesamt gibt es drei Schleifentypen in C++. Mit allen lässt sich diese Beispielaufgabe realisieren,
jedoch wird man feststellen, dass einige Typen besser dafür geeignet sind als andere. Aus diesem
Grund möchte ich nun jeweils die einzelnen Schleifentypen erklären und mit jedem dieser die
Beispielaufgabe lösen.
©Konstantin Rink
37 | S e i t e
C++
Die while-Schleife
Syntax:
}
while(<Bedingung>){
<sich wiederholendes Ereignis>;
Der Kopf der while-Schleife ist simpel aufgebaut, man gibt lediglich die gewünschte Bedingung an.
Der Inhalt der Schleife (<sich wiederholendes Ereignis>) wird solange durchlaufen bzw. ausgeführt,
bis die Bedingung im Schleifenkopf ihre Gültigkeit verloren(false) hat.
Lösung des Beispiels mit der while-Schleife:
Erläuterung
Was Ihnen sicher aufgefallen ist, ist die Variable counter. Die Variable ist eine Zählervariable die dafür
sorgt, dass unsere Schleife nicht endlos läuft.
Würde man sie weglassen, wäre die Bedingung dafür, dass die Schleife läuft, nur die Zahl die der
Benutzer eingibt, sprich die Bedingung wäre die ganze Zeit wahr(true) und wir würden Unmengen
von Rauten auf dem Bildschirm sehen.
counter hat einen Startwert von 0 (Z.10) und wird immer um 1 pro Schleifendurchlauf erhöht(Z.13)
Irgendwann, je nach dem welchen Wert der Anwender eingegeben hat, wird die Bedingung false
werden und die Schleife abbrechen, da der Wert der Variable counter größer wäre als der Wert der
Variable zahl. Und wir werden unser gewünschtes Ergebnis auf dem Bildschirm sehen.
Mit dem Beispiel der Zahl 6 sollte unsere Konsolenausgabe so aussehen:
Bitte geben Sie eine Zahl ein: 6
######Drücken Sie eine beliebige Taste . . .
©Konstantin Rink
38 | S e i t e
C++
Die for-Schleife
Syntax:
for(<Zähler>;<Bedingung>;<Zähler erhöhen/erniedrigen>){
<sich wiederholendes Ereignis>;
}
Im Vergleich mit der Syntax der while-Schleife sieht man, dass ein paar Parameter mehr dazu
gekommen sind. Erinnern wir uns an die Zählervariable counter, diese wurde vor der Schleife
definiert und wurde im Schleifenkörper immer um eins erhöht.
Dieses etwas umständliche hin und her nimmt uns die for-Schleife ab. Hier wird alles im
Schleifenkopf festgelegt. Im ersten Parameter legen wir unsere Zählervariable fest, im Zweiten wie
gewohnt unsere Bedingung und bei dem Dritten legen wir fest um wie viel unsere Zählervariable
erhöht/erniedrigt werden soll.
Unsere Lösung nach dem Beispiel würde dann so aussehen:
©Konstantin Rink
39 | S e i t e
C++
Die do-while-Schleife
Syntax:
do{<Ereignis>;
}while(<Bedingung>)
Unser letzter Kandidat ist die do-while-Schleife. Die Funktion verwendet auch die gleichen Parameter
wie die while-Schleife. Aber die Besonderheit dieses Typs ist, dass zuerst das Ereignis ausgeführt wird
und erst danach die Bedingung geprüft wird.
Sprich, beim ersten Durchlauf der Schleife wird nicht überprüft ob die Bedingung wahr(true) ist
sondern es wird einfach das Ereignis ausgeführt.
Für unsere Beispielaufgabe spielt es keine Rolle, dass das Ereignis vor der Bedingung ausgeführt wird.
Jedoch werden Sie auf Problemstellungen treffen, an denen die Vorteile dieses Schleifentyps wichtig
sind und es einen Unterschied macht, ob erst das Ereignis ausgeführt und erst danach die Bedingung
geprüft wird.
Lösung:
©Konstantin Rink
40 | S e i t e
C++
Eine Schleife vorzeitig abbrechen/Prozedur in einer
Schleife überspringen
Manchmal ist man gezwungen eine Schleife vorzeitig abbrechen zu lassen.
In C++ gibt es daher den Befehl break.
break bewirkt, dass die Schleife sofort verlassen wird.
Bemerkung: Wird der break-Befehl in verschachtelten Schleifen angewandt, wird nur die
unmittelbare Schleife verlassen.
Hier ein Beispiel indem ein Wertebereiche untersucht werden soll, befindet sich die Eingabe des
Anwenders im Zahlenbereich von 0 bis 4, so wird die Schleife abgebrochen, ansonsten läuft sie
durch.
Bildschirmausgabe wenn Zahl innerhalb des Wertebereichs liegt:
Bitte Zahl eingeben: 2
Drücken Sie eine beliebige Taste . . .
Bildschirmausgabe wenn Zahl außerhalb vom Wertebereich liegt:
Bitte Zahl eingeben: 5
0
1
2
3
4
5
6
7
8
9
Drücken Sie eine beliebige Taste . . .
©Konstantin Rink
41 | S e i t e
C++
Möchte man allerdings nur eine gewisse Prozedur in einer Schleife überspringen, verwendet man
den Befehl continue. Die continue-Anweisung springt dann wieder zum Anfang der Schleife und
überspringt somit die Ereignisse die zwischen dem Schleifenkopf und dem continue-Befehl liegen. Im
Vergleich zu break wird die Schleife somit nicht verlassen.
Hierzu auch ein Anwendungsbeispiel in dem ich alle Werte außer 5 ausgeben lassen möchte:
Bildschirmausgabe:
12346789
Drücken Sie eine beliebige Taste . . .
Wann verwende ich welche Schleife?
Zum Teil ist die Anwendung von den jeweiligen Schleifentypen Geschmackssache, jedoch kann man
teils auch klare Unterscheidungen treffen.
Die while-Schleife wird gerne verwendet, wenn die Anzahl der Daten mit denen man Arbeitet
unbekannt ist.
Die for-Schleife findet gerne ihre Anwendung, wenn die Anzahl der Daten wiederum bekannt ist.
Die do-while-Schleife wird verwendet, wenn man den Schleifenkörper mindestens 1x ausführen
möchte.
©Konstantin Rink
42 | S e i t e
C++
Eindimensionale Felder (Arrays)
Nachdem wir die Kapitel Variablen und Schleifen bearbeitet haben, kommen wir nun zu den Feldern,
im englischen arrays genannt.
Ein Array ist sozusagen eine Variable, in der mehrere Variable abgespeichert werden und deren
Werte durch einen jeweils eindeutigen Index angesprochen werden können.
Eine sehr gute Hilfe ist es, sich eindimensionale Arrays wie
ein eindimensionale Tabellen vorzustellen.
Jedem Wert wird ein Index von 0 aufsteigend zugewiesen.
Möchte man später mit einem bestimmten Wert arbeiten,
so kann man ihn über seinen Index ansteuern.
Index
0
1
2
3
Werte
Wert 1
Wert 2
Wert 3
Wert 4
Definition und Initialisierung von eindimensionalen Arrays
Syntax:
<Datentyp> <Name des Arrays>[<Größe des Arrays> bzw. <Anzahl der Zeilen>];
Codebeispiel:
©Konstantin Rink
43 | S e i t e
C++
Vorgang:
1. Bestimmen welche Art von Daten mein Array enthalten wird (int, float, double, etc.)
2. Dem Array einen Namen geben und festlegen wie viel Werte es maximal aufnehmen kann.
3. Initialisierung meines Arrays, indem ich jedem Wert einen Index zuweise.
Einlesen /Ausgeben von eindimensionalen
Arrayinhalten mit Schleifen
In diesem Unterkapitel möchten wir uns mit dem Einlesen und Ausgeben von Arrayinhalten
beschäftigen. Wie bei der Einleitung von Kapitel XX –Schleifen kurz erwähnt, werden Schleifen
verwendet, sobald man mit mehreren Arrayinhalten arbeiten möchte.
Im folgenden Quellcode-Beispiel möchte ich zeigen wie man mithilfe einer for-Schleife ein Array
durch eine Eingabeaufforderung befüllt.
Bildschirmausgabe:
Bitte Wert 0 festlegen: 1
Bitte Wert 1 festlegen: 2
Bitte Wert 2 festlegen: 3
Bitte Wert 3 festlegen: 4
Bitte Wert 4 festlegen: 5
Drücken Sie eine beliebige Taste . . .
Erläuterung
Zu Beginn legen wir fest wie groß unser Array zahlen maximal sein darf (Z.6), danach legen wir die
Bedingung für unsere Schleife fest.
Die Schleife wird 5 Runden durchlaufen, danach wird ihre Bedingung ungültig (false) werden, da die
Zählervariable counter je Runde um 1 erhöht wird (Z.9)
Im Schleifenkörper wird der Benutzer pro Durchlauf gebeten eine Zahl einzugeben. Die eingegebene
Zahl wird dem jeweiligen Index unseres Arrays zugeteilt (Z.12)
Nachdem wir nun unser Array durch eine Eingabeaufforderung befüllt haben, kommen wir nun zur
Ausgabe. Hierzu verwenden wir wieder eine for-Schleife.
©Konstantin Rink
44 | S e i t e
C++
Codebeispiel:
Bildschirmausgabe:
Bitte Wert 0 festlegen: 1
Bitte Wert 1 festlegen: 2
Bitte Wert 2 festlegen: 3
Bitte Wert 3 festlegen: 4
Bitte Wert 4 festlegen: 5
1
2
3
4
5
Drücken Sie eine beliebige Taste . . .
©Konstantin Rink
45 | S e i t e
C++
Einen bestimmten Wert von einem Array ausgeben
Möchte ich nun einen bestimmten Wert in einem Array ansteuern und diesen z.B. auf dem
Bildschirm ausgeben, geschieht dies indem ich den gewünschten Index des Arrays in die eckigen
Klammern ([X]) schreibe.
In diesem Beispiel habe ich ein Array mit den Buchstaben von A-K. Möchte ich mir nun den
Buchstaben G ausgeben lassen geschieht dies folgender Maßen:
Erläuterung:
Zuerst definieren und initialisieren wir unser Array mit Werten, in diesem Fall mit Buchstaben.
Aus diesem Grund verwenden wir auch den Typ char. (Z. 7)
In Zeile 10 lassen wir unseren gewünschten Buchstaben auf dem Bildschirm ausgeben, indem wir
den jeweiligen Wert (in diesem Fall „G“) über seine Indexnummer
0
A
ansprechen.
1
B
2
C
Der Index beginnt immer mit 0 aufsteigend, deswegen
3
D
steht auch die Indexnummer 6 und nicht die 7 in den eckigen Klammern.
4
E
5
F
Zum besseren Verständnis kann man sich das Array auch als
6
G
eindimensionale Tabelle vorstellen:
7
H
8
I
9
J
10
K
©Konstantin Rink
46 | S e i t e
C++
Mehrdimensionale Arrays
Bisher haben wir uns nur mit eindimensionalen Feldern bzw. Arrays beschäftigt, in Tabellenform
würde das bedeutet, dass wir bisher immer nur eine Spalte und x-beliebige Zeilen zur Verfügung
hatten. Die mehrdimensionalen Arrays bieten uns die Möglichkeit für x-beliebige Spalten und Zeilen.
Syntax:
<Datentyp> <Name des Arrays>[<Anzahl der Zeilen>][<Anzahl der Spalten>];
Wie man sehen kann, ist ein neuer Ausdruck ([<Anzahl der Spalten>]) hinzugekommen.
Nehmen wir als Beispiel ein Array namens „Tabelle“ mit 5 Zeilen und 3 Spalten, in C++ würde das
dann so aussehen: Tabelle[5][3];
In Tabellenform dürfen wir uns das dann so vorstellen:
Wert 1
Wert 2
Wert 3
Wert 4
Wert 5
Wert 6
Wert 7
Wert 8
Wert 9
Wert 10
Wert 11
Wert 12
Wert 13
Wert 14
Wert 15
Die Initialisierung sieht wie folgt aus:
Die Initialisierung würde in Tabellenform so aussehen.
1.5
1.7
5.2
6.1
7.8
2.5
2.7
5.3
6.8
7.6
©Konstantin Rink
3.5
3.7
5.8
6.4
7.4
Wie man erkennen kann, werden Arrays in C++ zeilenweiße
initialisiert. Der letzte Index [3] ändert sich also schneller wie der
erste Index [5].
47 | S e i t e
C++
Einlesen /Ausgeben von mehrdimensionalen
Arrayinhalten mit Schleifen
Im folgenden Beispiel möchten wir den Benutzer auffordern ein zweidimensionales (2 Spalten XZeilen) Array mit jeweils Stückzahl und Stückpreis zu befüllen.
Erläuterung:
Im Prinzip ähnlich wie bei den eindimensionalen Arrays. Nur möchten wir in diesem Beispiel ein Array
mit 2 Spalten verwenden. In der ersten Spalte möchten wir unsere Stückzahlen eingeben in die
zweite die Stückpreise.
In Zeile 12 steuern wir deshalb die Spalte 0 und in Zeile 15 die Spalte 1 an. Durch die Zählervariable i
werden die Zeilen zu den jeweiligen Spalten fortlaufend vom Benutzer beschrieben.
Die Ausgabe sieht auch wieder ähnlich wie bei den eindimensionalen Arrays aus:
©Konstantin Rink
48 | S e i t e
C++
Bildschirmausgabe mit zufällig eingegebenen Werten:
Bitte geben Sie die Stueckzahl ein: 200
Bitte geben Sie den Stueckpreis ein: 1.48
Bitte geben Sie die Stueckzahl ein: 500
Bitte geben Sie den Stueckpreis ein: 0.49
Bitte geben Sie die Stueckzahl ein: 200
Bitte geben Sie den Stueckpreis ein: 5.69
Bitte geben Sie die Stueckzahl ein: 800
Bitte geben Sie den Stueckpreis ein: 1.89
Danke fuer Ihre Eingabe.
Stueckzahl || Stueckpreise
200 || 1.48
500 || 0.49
200 || 5.69
800 || 1.89
Drücken Sie eine beliebige Taste . . .
Einen bestimmten Wert von einem mehrdimensionalen
Array ausgeben
Möchte man nun beispielsweise den Wert7 ansprechen, stellt man sich am besten eine Tabelle vor:
Unser gesuchter Wert befindet sich also in
Spalte 1 (da der Index immer mit 0 beginnt)
und Zeile 1.
In der C++ sähe es dann so aus:
Wert 1
Wert 2
Wert 3
Wert 4
Wert 5
Wert 6
Wert 7
Wert 8
Wert 9
Wert 10
Wert 11
Wert 12
Wert 13
Wert 14
Wert 15
Parallel dazu als Tabellenform:
1.5
1.7
5.2
6.1
7.8
©Konstantin Rink
2.5
2.7
5.3
6.8
7.6
3.5
3.7
5.8
6.4
7.4
49 | S e i t e
C++
Bubblesort und Dreieckstausch
Je nach Problemstellung werden wir irgendwann an den Punkt kommen, wo wir Werte in einem
Array sortieren oder vertauschen möchten. Hierfür soll der Sortieralgorithmus Bubblesort und das
Verfahren des Dreieckstauschs Abhilfe schaffen.
Dreieckstausch
Beim Dreieckstausch hilft uns eine Hilfsvariable, Werte in einem Array zu vertauschen.
Dabei wird der Wert des Arrays der zuerst überschrieben wird, in einer Hilfsvariablen
zwischengespeichert.
Folgendes Beispiel soll uns den Problemfall erläutern:
Bevor wir uns an die Arbeit machen, hier der Dreieckstausch als Pseudocode zum besseren
Verständnis:
temp := v1 // Die Hilfsvariable nimmt den Wert der zu vertauschenden Variable an.
v1 := v2 // Variable 1 wird jetzt der Wert der Variable 2 zugewiesen.
v2 := temp // Zum Schluss erhält Variable 2 den Anfangswert der Variable 1
Umgesetzt in unsere C++ Sprache würde es dann so aussehen:
©Konstantin Rink
50 | S e i t e
C++
Abschließend möchte ich noch eine weitere Aufgabenstellung zeigen.
Diesmal möchten wir, dass der Benutzer die Möglichkeit hat selbst zu bestimmen an welcher Stelle
der erste Wert durch-getauscht werden soll.
Erläuterung:
Anfangs mag der Dreieckstausch noch etwas kompliziert aussehen, man muss aber einfach nur
zwischen aktuellen Wert und aktuellen Index unterscheiden.
Schauen wir uns die Schleife mal im ersten Durchlauf an:
Unsere Hilfsvariable hilf bekommt den Wert der Indexnummer 0 unseres Arrays zugewiesen, also 1.
Danach bekommt unser Array an die Stelle mit der Indexnummer 0 den Wert der Indexnummer 1
zugewiesen, also 2.
Im letzten Schritt bekommt die Stelle mit der Indexnummer 1 mit Hilfe der Hilfsvariablen den
ehemaligen Wert mit der Indexnummer 0 zugewiesen.
An der Indexnummer 0 steht jetzt der Wert der Indexnummer 1 und umgekehrt.
Bildschirmausgabe mit dem eingegebenen Wert 5:
An welche Stelle soll unser erstes Array getauscht werden: 5
23456178910
Drücken Sie eine beliebige Taste . . .
©Konstantin Rink
51 | S e i t e
C++
Bubblesort
Der Bubblesort Algorithmus wird verwendet, wenn man Werte in einem Array sortieren möchte.
Um einen guten Einstieg in diesen Algorithmus zu erhalten, nehmen wir ein Kartenbeispiel zur Hand.
Wie wir sehen sind die Karten der ihrer Wertung nach aufsteigend sortiert.
Jetzt vermischen wir die Karten willkürlich.
Der Bubblesort Algorithmus soll uns jetzt helfen, diese Karten wieder in die richtige Reihenfolge zu
bringen.
Dabei macht der Algorithmus folgendes:
Er vergleicht immer die linke Karte mit seinem rechten Nachbarn, in unserem Fall vergleicht er also
Pik 8 mit Pik 7.
Ist die linke Karte größer wie sein Nachbar, werden die beiden Karten vertauscht:
Dieses Vertauschen wird solange durchgeführt, bis die Karten der Größe nach in der richtigen
Reihenfolge sortiert sind.
Bevor wir nun zur eigentlichen Programmierung in C++ kommen, sollten wir uns den Algorithmus als
Struktogramm ansehen:
©Konstantin Rink
52 | S e i t e
C++
Die Quellcodeversion:
Erläuterung
Wir gehen von einem Array namens zahlen aus, welches Werte von 1-10 in nicht sortierter
Reihenfolge enthält. Um zu verstehen, was jede einzelne Schleife macht, schauen wir uns die ersten
3 Durchläufe an. Wir betrachten die innere for-Schleife:
Erster Durchlauf:
Zahlen[0] < zahlen[0] // 6<6
Zweiter Durchlauf:
Zahlen[0]<zahlen[1] //6<3
Dritter Durchlauf:
Zahlen[0]<zahlen[2] //6<7
An dieser Stelle ist unsere if-Funktion wahr und er vertauscht die Werte 6 und 7.
©Konstantin Rink
53 | S e i t e
C++
Arbeiten mit Arrays
In diesem Kapitel sind einige Aufgaben zu bearbeiten, in denen die Basics von Arrays und Schleifen
Voraussetzung sind. Diese Aufgaben sollten den Grundumgang mit Arrays abdecken. Die Lösungen
sind auf der nächste Seite zu finden.
Aufgabe #1:
Schreiben Sie ein Programm, welches die Summe aus 3 eigegebenen
Fließkommawerten berechnen soll.
Aufgabe #2:
Schreiben Sie ein Programm, welches zuerst 5 Messwerte in ein Array einlesen soll und
danach den Durchschnitt aus dieser Messwerte berechnet.
Aufgabe #3:
Schreiben Sie eine Anwendung in der unsere wissenschaftlichen Mitarbeiter den
Wochentag(in den Zahlen 1-6) und ihr jeweiliges Messergebnis für eine Woche (6
Arbeitstage) eintragen können. Nach ihrer Eingabe sollen sie in einer Spalte die
Wochentage und in einer anderen die Messwerte ausgegeben bekommen.
Zum Beispiel:
Wochentag || Messwert
1
|| 34,5
Aufgabe #4: - Noch keine Lösung Schreiben Sie eine Anwendung für ein Kassensystem. Der Verkäufer gibt die Stückzahl
und den Verkaufspreis ein und bekommt den zu Zahlenden Betrag zurückgeliefert.
(Wir gehen von Maximal 10 Artikeln pro Einkauf aus)
Aufgabe #5:
Etwas Mathematik gefällig?
Unter einer Spur versteht man die Quersumme einer Matrix. Schreiben Sie für eine 3x3
Matrix eine Anwendung, die die Quersumme bzw. die Spur errechnet.
Die Werte der 3x3 Matrix können Sie mit beliebigen Werten initialisieren.
©Konstantin Rink
54 | S e i t e
C++
Lösungen
In der Programmierung gibt es meist immer mehrere Lösungsmöglichkeiten, aus diesem Grund kann
es sein, das Ihr Quellcode von dem der Musterlösung abweichen kann.
Aufgabe #1:
Aufgabe #2:
©Konstantin Rink
55 | S e i t e
C++
Aufgabe #3:
Aufgabe #5:
In diesem Fall wäre das Ergebnis 15. Um sich den Verlauf der Schleife besser vorzustellen, sollte man
wieder mit einer Tabellen-Skizze arbeiten und einen einzelnen Schleifendurchlauf analysieren.
©Konstantin Rink
56 | S e i t e
C++
Funktionen
Bisher haben wir unsere Berechnungen immer in der main-Funktion durchgeführt. Jedoch werden
wir schnell in der Programmierung an einen Punkt kommen, wo wir z.B. gewisse Rechenoperationen
(z.B. die Berechnung von Quadratmeter) häufiger als nur einmal durchführen möchten.
Nach unseren bisherigen Wissenstand müssten wir also immer wieder, wenn wir den Term
benötigen, diesen in unserem Quellcode schreiben. Zugegeben, bei der Berechnung von
Quadratmetern würde uns das noch wenig ausmachen, jedoch ist dies nur ein sehr simples Beispiel.
Viel einfacher wäre es doch, diesen Term auszulagern und bei Bedarf einfach die benötigten
Parameterwerte (z.B. Länge und Breite) ihm zu übergeben und das Ergebnis zurück geliefert
bekommen. Und genau an diesem Punkt kommen die Funktionen ins Spiel.
Syntax:
}
<Datentyp> <Name der Funktion>(<Datentyp><Parameter1>,<Datentyp><Parameter2>){
<Ereignisse>;
Wie Sie sicher festellen werden, hat die Syntax von Funktionen den gleichen syntaktischen Aufbau
wie unsere main-Funktion. Selbstverständlich, schließlich ist die main-Funktion prinzipiell auch nichts
anderes wie eine normale Funktion. Doch wie in Kapitel XX erwähnt, hat die main-Funktion die
Besonderheit, dass sie quasi die Einstiegsfunktion unseres Programmes ist. Sie ist sozusagen die
Funktion auf die beim Start unseres Programmes als erstes zugegriffen wird und die jeweiligen
Befehle in ihr ausgeführt werden.
Folgender Quellcode als Beispiel:
Bevor wir auf die einzelnen Begrifflichkeiten wie return eingehen, möchten wir uns die Schreibweise
der Funktionen genauer ansehen. In diesem Beispiel wird unser Programm funktionieren, schreiben
wir jedoch die Funktion quadratmeter nicht ober- sondern unterhalb der main-Funktion werden wir
eine Fehlermeldung von unserem Compiler erhalten.
Da unser Compiler immer von oben nach unten liest, wüsste er in Zeile 17 somit nicht, dass
überhaupt eine Funktion quadratmeter existiert.
©Konstantin Rink
57 | S e i t e
C++
Später werden wir mit mehr als nur einer Funktion arbeiten und evtl. möchten wir, dass die
Funktionen jeweils aufeinander zugreifen können (z.B. eine Funktion berechnet die Längen, eine
andere übernimmt diese Werte und berechnet den Flächeninhalt). Dann müssten wir uns an eine
gewisse Hierarchie halten, da wir genau wissen müssten, welche Funktion wir zuerst deklarieren und
definieren, sonst würden wir wieder eine Fehlermeldung vom Compiler bekommen, dass die
gewünschte Funktion noch nicht existiert. Um das zu vermeiden, werden wir zu Beginn immer
unsere Funktionen deklarieren und später an beliebiger Stelle definieren.
Syntax:
<Datentyp> <Name der Funktion>(<Datentyp>,<Datentyp>); // Deklaration
...
…
<Datentyp> <Name der Funktion>(<Datentyp><Parameter1>,<Datentyp><Parameter2>){
<Ereignisse>;
} // Definition
Somit ist es jetzt egal an welche Stelle wir in unserem Programm unsere Funktion definieren.
Unser Codebeispiel würde dann so aussehen:
Unser Compiler liest immer von oben nach unten, kommt er an Zeile 4 an, springt er zu Zeile 16 um
dort unsere Funktion quadratmeter einzulesen. So kann man diese beliebig später im Quellcode
verwenden.
©Konstantin Rink
58 | S e i t e
C++
Rückgabewert
Sicher haben Sie sich schon gefragt, was der return-Befehl zu bedeutet hat.
Der return-Befehl beendet die Funktion und liefert den jeweiligen Wert (in unserem Beispiel den
Wert der Variable ergebnis) zurück.
Wichtig ist, dass wir wissen, welchen Typ von Wert uns unsere Funktion zurückgeben soll. Sprich, ob
es sich beispielsweise um eine Ganzzahl oder Fließkommazahl handelt. Mit dieser jeweiligen Art
müssen wir unsere Funktion deklarieren (Z.4, Z.16). In unserem Fallbeispiel wird also eine Ganzzahl
(int)zurückgeliefert.
Hier noch einige Schreibweisen wie man sich Werte in C++ zurückliefern lassen kann:
Es gibt auch Funktionen, die uns keinen Wert zurückliefern sondern lediglich z.B. einen Wert
ausgeben sollen. Diese Funktionen deklariert man dann mit void und kann auf den return-Befehl
verzichten bzw. der return-Wert wäre 0. Ein Beispiel hierzu:
Nun wissen wir, wie wir eine neue Funktion erstellen und wie wir uns Werte aus Funktionen mit
return zurückliefern lassen. Sollte man einen return vergessen ist der Rückgabewert der Funktion
undefiniert und zufällig. Manche Compiler geben dann dementsprechend eine Fehlermeldung über
den fehlenden Rückgabewert aus.
Kommen wir nun dazu wie wir Parameterwerte an Funktionen übergeben. Hierzu gibt es die
Möglichkeiten call by value und call by reference.
©Konstantin Rink
59 | S e i t e
C++
Call by value
-Der Standardfall-
In den bisherigen Beispielen haben wir den Standartfall call by value schon unbewusst verwendet.
Wenn wir eine Funktion aufrufen, werden nur die Werte der einzelnen Parameter übergeben („call
by value“). Das heißt, unsere Funktion kann nur lesend, aber nicht schreibend auf die übergebenen
Parameter zugreifen. Der Vorteil dieser Parameterübergabe ist es, das keine unbeabsichtigten
Änderungen von Variablenwerten durch diese Aufrufe in anderen Funktionen(z.B. der mainFunktion) auftreten können.
Beachte:
Ausgenommen von dieser Regel sind Vektoren, Strings und Arrays. Werden sie an eine Funktion
übergeben, kann die Funktion auch übergreifend schreibend auf die Parameter zugriff nehmen.
Ein Beispiel soll uns den Fall erläutern:
Wir möchten zu den Variablen a und b jeweils 2 hinzuaddieren, danach a und b multiplizieren und
uns das Ergebnis ausgeben lassen.
Bildschirmausgabe:
a hat den Wert: 2
b hat den Wert: 4
Das Ergebnis lautet: 24
Drücken Sie eine beliebige Taste . . .
Obwohl wir in unserer Funktion addition zu den Variablen a und b +2 hinzuaddiert haben, hat sich ihr
Wert in der main-Funktion nicht geändert, sondern lediglich in unserer Funktion addition. Das ist der
Vorteil der Parameterübergabe call by value.
©Konstantin Rink
60 | S e i t e
C++
In diesem Beispiel möchten wir uns nun ansehen, was passiert wenn wir Arraywerte an eine Funktion
übergeben.
Bildschirmausgabe:
0--5
Drücken Sie eine beliebige Taste . . .
Wie wir gelernt haben, liefert uns unsere Funktion immer nur das zurück, was mit dem return-Befehl
zurückgegeben wird. Jedoch wurde auch unser Array verändert. Normalerweise hat unser Array an
der Stelle [0] den Wert 1. Jedoch passierte bei der Werteübergabe an die Funktion addition
folgendes: Bei Arrays wird auch bei der call by value Übergabe die Speicheradresse des Arrays
übermittelt. Die Funktion hat dann auch schreibzugriff auf den Array und kann dessen Werte
dauerhaft verändern. Aus diesem Grund sollte man aufpassen, wenn man Arraywerte an eine
Funktion übergibt.
Wie wir es realisieren, dass die Speicheradressen von Variablen mit übergeben werden und eine
Funktion somit auch schreibzugriff auf Variablen erhält sehen wir im nächsten Unterkapitel.
©Konstantin Rink
61 | S e i t e
C++
Call by reference
Diese Parameterübergabe ist das Gegenstück zur call by value-Übergabe. Die Speicheradressen von
Variablen(siehe Kapitel XX) werden mithilfe von Zeigern (siehe Kapitel XX) als Funktionsparameter an
die Funktion übergeben. Damit ist es der Funktion möglich auch funktionsübergreifend schreibend
auf die Variablen Zugriff zu nehmen.
Syntax:
<Datentyp> <Name der Funktion>(<Datentyp> Zeiger,<Datentyp> Zeiger);
...
…
<Datentyp> <Name der Funktion>(<Datentyp>Zeiger auf<Parameter1>,<Datentyp>Zeiger
auf<Parameter2>){
<Ereignisse>;
}
Ein Quellcodebeispiel zum Verständnis:
Bildschirmausgabe:
b hat den Wert: 5
c hat den Wert: 11
Drücken Sie eine beliebige Taste . . .
©Konstantin Rink
62 | S e i t e
C++
Erläuterung:
Wie in der Syntax schon angegeben, wird bei der call by reference-Übergabe mit Zeigern(=Pointer)
gearbeitet. In Zeile 5 bei der Deklaration werden die Parameter als „Zeiger auf int“ deklariert.
In Zeile 11 werden der Funktion die Speicheradressen der Variablen mithilfe des Adressoperators &
übergeben.
In Zeile 24 und 25 greift man jetzt mithilfe von Zeigern auf die Werte der Variablen zu und verändert
diese dauerhaft, da die Funktion schreibend Zugriff auf die Speicheradressen der Variablen hat.
Man hätte die Funktion veraendern auch als void deklarieren können, da diese Funktion uns nichts
(0) zurückliefert.
©Konstantin Rink
63 | S e i t e
C++
Grafikquellen:
Designer Iconshock
License: Free for personal use (Buy commercial license at Iconshock)
Icon set Brilliant
Designer Julian Turner
License: Creative Commons (Attribution-Share Alike 2.0 Generic)
Icon set Still life
Designer Alexandre Moore
License: GPL
Icon set Vista Inspirate
Designer Harwen Zhang
License: Free for personal use only
Icon set Simple
http://lipidity.com/wordpress/wp-content/uploads/2007/04/obj-c-header.png
by Alexandre Moore | Vista Inspirate
Application, Executable, Script, X icon
by Oliver Scholtz (and others)
©Konstantin Rink
64 | S e i t e

Documentos relacionados