Einführung in C++ (Teil 2)
Arrays sind Datenfelder, in denen sich mehrere Datenelemente desselben Datentyps befinden, wobei auf die einzelnen Daten über einen Index zugegriffen werden kann. Sämtliche Daten haben zwar denselben Namen, können aber eindeutig vom Programm über eine Nummer angesprochen werden. Bei der Deklaration eines Feldes gibt man die Anzahl der Daten an, die das Feld speichern soll, sowie den für sämtliche Daten gültigen Datentyp.
Array-Deklaration: Datentyp Feldname[Anzahl]
Beispiel für Array-Deklaration: int a[100]Beispiel 1:
// Lese 5 Zahlen ein und gebe sie in umgekehrter Reihenfolge auf dem Bildschirm aus.
#include <iostream.h>
void main()Zweidimensionale Felder (Matrizen):
Eine Matrix kann man auffassen als einen Array, dessen Elemente wieder Arrays sind.
Deklaration: Datentyp Feldname[Anzahl1] [Anzahl2]Beispiel 2:
// Programm Matrix1: Ein- und Ausgabe der Matrix:
#include <iostream.h>
void main( )Beispiel 3:
//Programm Matrix2: Ein- und Ausgabe einer beliebigen 2x2 - Matrix.
#include <iostream.h>
void main( )Zeiger sind Variablen. Sie speichern aber im Gegensatz zu konventionellen Variablen Adressen.
Zeigerdeklaration: Datentyp *Variablenname
Um nur einige Vorteile zu nennen:|
Operator |
Bedeutung |
|
& |
Adresse |
|
* |
Inhalt |
Definition und Wertzuweisung von Zeigern:
Die Zuweisung einer Adresse an eine Zeigervariable erfolgt mit Hilfe des Adressoperators &.
Beispiel 4:
//Pointer1
#include <iostream.h>
void main()Die Variable x ist eine gewöhnliche int-Variable und p und px sind Pointervariablen (auch kurz Pointer genannt). Dem Pointer p wird als Wert eine Adresse zugewiesen: p = 0xbffff684. Die int-Variable x erhält den Wert 5. An der Stelle im Speicher des Computers, an der x gespeichert wurde, befindet sich jetzt der Wert 5. Im nächsten Schritt wird dem Zeiger px die Adresse von x zugewiesen. Der Zeiger px zeigt nun also auf die Variable x.
Man kann dies auf 2 Arten veranschaulichen:p = 0xbffff684; x = 5; px = &x:

p = 0xbffff684; x = 5; px = &x:

Zugriff auf den Wert der referenzierten Variablen:
Beispiel 5:
//Pointer2
#include <iostream.h>
void main()Output:
x = 4
x = 2
Veranschaulichung:
px = &x; x = 4:


Zuweisung zweier Zeiger:
Die Zuweisung einer Adresse an einer Zeigervariable kann auch durch Zuweisung einer anderen Zeigervariablen erfolgen.
Beispiel 6:
//Pointer3
#include <iostream.h>
void main()Veranschaulichung:
x = 4; y = 3; px = &x; py = &y:

px = py:

Zusammenhang zwischen Arrays und Pointers
Ein Zeiger kann nicht nur auf eine einzelne Variable, sondern auch auf ein Element einer Folge von Werten (Array) zeigen. Man kann den Namen einer Array-Variablen als Zeiger auf ihr erstes Element auffassen:
int a[100] //Array mit 100 Elementen vom Typ int
a ist identisch mit &a[0] //Der Bezeichner der Folge, nämlich a, ist gleichbedeutend mit dem ersten Element der Folge.Es gibt also neben der schon bekannten Methode eine zweite, mit der auf die Elemente eines Arrays zugegriffen werden kann (Beispiel 7).
Beispiel 7:
//Pointer4
#include <iostream.h>
void main()Die Unterprogramme in C++ heißen Funktionen. Dadurch entsteht die Möglichkeit eine einmal definierte Anweisungsfolge von einer beliebigen Stelle des Programms zu einem beliebigen Zeitpunkt aus "aufzurufen". Ein solcher Aufruf bewirkt, daß der Programmcode des Unterprogramms ausgeführt und nach dessen Ende mit der nächsten Anweisung hinter der Aufrufstelle fortgefahren wird.
Anmerkung: In C++ wird keine Unterscheidung zwischen Procedures (Subroutinen) und Funktionen gemacht!
|
Rückgabedatentyp Funktionsname(Parameterliste) { Anweisungen; return Wert; //nur wenn die Funktion einen Rückgabe- } //datentyp ungleich void hat. |
|
| Rückgabedatentyp Funktionsname(Parameterliste) | |
| Funktionsname(Parameterliste) |
Beispiel 8:
//Produkt zweier Zahlen a und b
#include <iostream.h>
int produkt(int a, int b)Der Funktionsaufruf geschieht durch produkt(x,y) in der
Funktion main. Dabei erfolgt ein Sprung zur Funktion produkt, die das Produkt
der Zahlen x und y berechnet und das Ergebnis mittels der Anweisung return an
die Funktion main zurückgibt. Das zurückgegebene Ergebnis tritt
dann an die Stelle des Funktionsaufrufs.
Die Parameter a und b treten als interne Variablen auf, die durch den
Funktionsaufruf die Werte von x und y als Anfangswert erhalten. Die
Parameterliste des Funktionsaufrufs erhält also die Namen der Variablen
die an die Funktion übergeben werden sollen.
Allgemeines:
Die Funktion produkt hätte auch hinter der Funktion main stehen
können. Sie muß dann allerdings zusätzlich in der Funktion
main deklariert werden. Dies geschieht durch:
int produkt(int a, int b);
Achtung: Funktionen können nie innerhalb anderer Funktionen stehen!
Beispiel 9:
//Lese 3 ganze Zahlen ein und gib die größte Zahl aus.
#include <iostream.h>
void main()Gültigkeitsbereiche von Variablen
Der Funktionskörper ist ein Block (durch geschweifte Klammern { } begrenztes Programmstück). Alle Variablen einer Funktion existieren somit nur in diesem Block, sind also anderen Funktionen völlig unbekannt. Diese Variablen bezeichnet man als lokale Variablen. Die in der Parameterliste aufgeführten Variablen nehmen eine Sonderstellung ein. Sie werden innerhalb der Funktion wie lokale Variablen betrachtet und stellen (von außen gesehen) die Datenschnittstelle zur Funktion dar. Weiterhin gibt es noch globale Variablen, die außerhalb von main und jeglicher anderer Funktion definiert werden. Sie sind in allen Teilen des Programms gültig.
Beispiel 10:
//Scope
#include <iostream.h>
int i = 1; //globale Variable, d.h. überall bekannt.
void funktion1()Die Variable i ist eine globale Variable, d.h. man kann sie in beiden Funktionen benutzen. Bei komplizierteren Programmen verliert man aber beim Arbeiten mit globalen Variablen schnell den Überblick. Das Programm wird meist schlecht lesbar und unnötig kompliziert.
Beispiel 11:
//Vertauschen zweier Werte x und y durch Gebrauch von globalen Variablen
#include <iostream.h>
int x,y;
void vertausche()Da globale Variablen verwendet werden, kann man mit Funktionen ohne Parameter arbeiten. Wie schon oben erwähnt, ist die Verwendung von globalen Variablen nicht zu empfehlen, da sie leicht zu Fehlern führen kann. Die Kommunikation zwischen verschiedenen Funktionen sollte daher möglichst über Parameter erfolgen (wie die nachfolgenden Beispiele zeigen werden).
Eine Möglichkeit des Datentransports ist die Übergabe per Wert. Dabei werden die Werte für x und y beim Funktionsaufruf als Kopie an die Funktion vertausche übergeben. Die Funktion vertausche arbeitet mit der Kopie, die Ausgangswerte für x und y beim Aufrufer bleiben unverändert erhalten.
Beispiel 12:
//Vertauschen zweier Werte x und y mittels Übergabe per Wert
#include <iostream.h>
void vertausche(int a, int b)Beispiel 13:
//Fehlgeschlagenes Vertauschen zweier Werte x und y mittels Übergabe per Wert
#include <iostream.h>
void vertausche(int a, int b)Die beiden Beispiel zeigen, daß die Kommunikation nur in der "Hinrichtung" funktioniert. In Beispiel 12 sieht man, daß die Werte von x und y in der Funktion vertausche tatsächlich vertauscht werden. Beispiel 13 zeigt jedoch, daß die Wertzuweisung bei a und b die Variablen x und y unverändert läßt.
Um eine Kommunikation in beide Richtungen zu erreichen, gibt es 2 Möglichkeiten:
Zu 1:
Beispiel 14:
//Vertauschen zweier Werte x und y durch Verwendung von Adressen und Pointer
#include <iostream.h>
void vertausche(int *a, int *b)Veranschaulichung:
In main: x = 5; y = 7;

Aufruf der Funktion vertausche: vertausche (&x, &y);

In Funktion vertausche:
h = *a:

*a = *b:

*b = h:

Zu 2:
Bei der Übergabe per Referenz wird im Gegensatz zur Übergabe per Wert direkt mit dem Original gearbeitet anstatt mit einer Kopie. Das &-Zeichen gibt an, daß nicht nur der Wert, sondern zusätzlich noch die Adresse übergeben wird. Wenn man also innerhalb der Funktion vertausche den Variablen a und b Werte zuweist, werden in Wirklichkeit die Variablen x und y der Funktion main verändert.
Beispiel 15:
//Vertauschen zweier Werte x und y mittels Übergabe per Referenz
#include <iostream.h>
void vertausche(int &a, int &b)