H A L L
O \0
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] |
Die ersten fünf Kästchen (Zählweise: 0 bis 4) sind klar, aber wer bewohnt denn da das sechste (Index: 5) Kästchen? Dieses Zeichen, nämlich die binäre Null (ASCII-Code 0), beendet in C/C++ einen klassischen C-String. Ebenso könnten z.B. auch Zahlen bzw. Zahlen und Buchstaben im Array stehen. Die "Bewohner" der "Kästchen" nennt man auch die Elemente des Arrays. Arrays bezeichnet man auch als Felder oder Vektoren (eindimensional) bzw. Tabellen (mehrdimensional).
Ein Array ist also ein Feld mit einer festgelegten Anzahl von Elementen des gleichen Typs (bool, char, int, float, double etc.). Der Typ der Elemente und damit der Speicherbedarf pro Element wird bei der Deklaration, z.B. char eingabe[80], festgelegt. In der eckigen Klammer steht die Gesamtzahl der Elemente.
The first five boxes (counting: 0 to 4) are clear, but who lives in the sixth (index: 5) box? This character, namely the binary null (ASCII code 0), terminates a classic C-string in C/C++. Similarly, for example, numbers or numbers and letters could also be stored in the array. The "residents" of the "boxes" are also called the elements of the array. Arrays are also referred to as fields or vectors (one-dimensional) or tables (multi-dimensional).So an array is a field with a fixed number of elements of the same type (bool, char, int, float, double, etc.). The type of the elements and thus the storage requirement per element is determined during declaration, for example, char input[80]. The total number of elements is specified in the square brackets.
Important: The numbering of the elements in an array in C++ does not begin with [1], but with [0]. For example, the first element of eighty is eingabe[0], and the last element is eingabe[79].
Beispiel: Bei der Programmierung von Schleifen durchläuft
man 80 Elemente, indem man den Schleifenzähler i nicht von 1 bis 80,
sondern von 0 bis 79 zählt.
Example: When programming loops, one goes through 80 elements by counting the
loop counter i not from 1 to 80, but from 0 to 79.
In den nachfolgenden kleinen Programmen lesen wir mittels der Funktion cin einen Zeichenstring ein. Diese Strings bestehen aus einzelnen Zeichen. Bei Worten sind dies Buchstaben, die als Elemente in das Array eingabe[80] eingehen. Dieses Array umfasst gemäß Deklaration Speicherplatz für 81 Elemente des Typs char. Wir werden den Umgang mit den Strings, die in dem Array gespeichert sind, nun trainieren, damit die Wirkung von Adressen und Zeigern klarer wird.
Als Beispiel benutzen wir das Wort "Jahrhundert".
Der C++-Stream cin liest den String ein und speichert ihn im Array eingabe
[80].
Im Speicher befinden sich daraufhin folgende
Daten des Typs char:
|J|a|h|r|h|u|n|d|e|r|t|\0|
Der String wird durch "\0" abgeschlossen, das heißt wir können im Array eingabe[80] mit seinen insgesamt 80 Elementen des Typs char maximal 79 Zeichen (character) gefolgt von der binären Null ablegen. Die einzelnen Elemente des Strings (also die einzelnen Zeichen) können direkt über den Namen eingabe[i] angesprochen werden. In eingabe[0] findet sich z.B. das Zeichen 'J'. Hier werden gezielt Hochkommas benutzt, da Anführungszeichen ("...") für Zeichenketten (Strings) eingesetzt werden, und diese beinhalten an ihrem Ende "\0".
In the following small programs, we read in a character string using the cin function. These strings consist of individual characters. For words, these are letters that go into the input[80] array as elements. According to the declaration, this array includes storage space for 81 elements of type char. We will now practice handling the strings stored in the array so that the effect of addresses and pointers becomes clearer.As an example, we use the word "Jahrhundert". The C++ stream cin reads in the string and stores it in the input[80] array. The following data of type char are then stored in memory:
Jedes Element hat im Array eine Nummer, z.B. die [0] für 'J'. Die Variable eingabe[0] hat jedoch auch eine Adresse im Speicher des Computers. Diese Speicheradresse des "Kästchens" eingabe[0] findet man über &eingabe[0]. Das vorangestellte & (Adress-Operator) vor dem Element des Arrays bewirkt, dass wir uns nicht auf den Inhalt, sondern auf die Speicheradresse des "Kästchens" beziehen. Zusätzlich erlaubt C++ hier eine gleichwertige Schreibweise, die jedoch am Anfang eher zur Verunsicherung beiträgt. Durch Weglassen der eckigen Klammern wird der Name des (eindimensionalen) Arrays zur Anfangsadresse:
&eingabe[0] ist die Speicheradresse von eingabe[0] und kann äquivalent als eingabe geschrieben werden.
Zusätzlich bringen wir an dieser Stelle
noch den Inhalts-Operator * (auch indirection-Operator oder Dereferenzierungs-Operator
genannt),
der uns den Inhalt einer Adresse übergibt:
*&eingabe[0] ist der Inhalt der
Adresse und daher gleichwertig mit eingabe[0].
Jetzt betrachten wir dies in der Programmierpraxis.
Das nachstehende Programm (array001) kann uns helfen, den Aufbau von Arrays
zu verstehen. Wir geben z.B. den Zeichenstring "Jahrhundert" in eingabe[80]
ein und belegen damit inclusive \0 die ersten 12 Plätze also die Elemente
0 ... 11 des Arrays. Die for-Schleife gibt nun beginnend (i=0) mit eingabe[0]
nacheinander die einzelnen Elemente eingabe[i] aus.
Die Bedingung eingabe[i]!='\0' beendet die for-Schleife,
sobald das Zeichen '\0' gefunden wird.
'\0' wird nicht mehr ausgegeben.
Now let's look at this in programming practice. The following program
(array001) can help us understand the structure of arrays. For example, we
enter the character string "Jahrhundert" in eingabe[80], thus occupying the
first 12 positions, i.e. elements 0 ... 11 of the array, including \0. The
for-loop then outputs the individual elements eingabe[i] starting with
eingabe[0]. The condition eingabe[i]!='\0' terminates the for-loop as soon as
the character '\0' is found. '\0' is not output anymore.
//Programm array001.cpp
#include
<iostream> int main()
|
Jetzt ändern wir eingabe[i] in *&eingabe[i] ab, um die Wirkung von "Inhalt der Adresse ..." zu überprüfen.
If we change "eingabe[i]" to "*&eingabe[i]", we are effectively dereferencing
the address of "eingabe[i]" to get the value stored at that address.
//Programm array002.cpp
...
cout << *&eingabe[i]; // identisch mit eingabe[i]
...
Bei beiden Programmen erhalten wir folgende Bildschirmausgabe:
Jahrhundert (eingegebener String)
Jahrhundert (ausgegebener String)
Sie haben damit Grundfunktionen kennen gelernt, um einen String in ein Array einzulesen und aus diesem wieder vollständig auszulesen.
Ändern Sie das Programm jetzt wie folgt
ab:
//Programm array003.cpp
#include
<iostream>
int main()
|
Jahrhundert
JJJJJJJJJJJ
Was bedeutet *eingabe noch einmal genau?
eingabe war identisch mit &eingabe[0].
Damit wird *eingabe zu *&eingabe[0].
Der Inhalt an der Speicheradresse des nullten Elements ist das nullte Element
und damit 'J'.
Dieses Element wird im Programmablauf solange
ausgegeben, bis die for-Schleife auf das String-Ende '\0' stößt.
Fassen wir kurz zusammen, was wir bisher mittels
cout in der for-Schleife ausgegeben haben:
What does *eingabe mean again exactly? eingabe was
identical to &eingabe[0]. Thus, *eingabe becomes *&eingabe[0]. The content at
the memory address of the zeroth element is the zeroth element itself, which is
'J'. This element is outputted repeatedly in the program until the for-loop
encounters the string end '\0'.
eingabe[i] | Elemente
des Arrays |
*&eingabe[i] | Inhalte
der Adressen der Elemente des Arrays ( = Elemente des Arrays ) |
*eingabe | Inhalt
der Startadresse des Arrays ( = nulltes Element des Arrays ) |
Jetzt testen wir den Adress-Operator ohne
Aufhebung durch den Inhalts-Operator:
// Programm array004.cpp
#include
<iostream> int main()
|
Jahrhundert
Jahrhundertahrhunderthrhundertrhunderthundertundertndertdertertrtt
Ja, das sieht ja lustig aus! Eigentlich hatten
wir unter Benutzung des Adress-Operators erwartet,
dass die Speicheradressen der Elemente des
Arrays nacheinander ausgegeben werden.
Stattdessen erhält man den gesamten String
ab der übergebenen Adresse.
Interessant, aber zunächst unlogisch. Sie
vermuten, dass dies mit einer Sonderbehandlung von
Strings durch C++ zusammenhängt? Es war
ja bereits merkwürdig, dass wir mit cin unter Angabe der Startadresse,
also eingabe (gleichbedeutend mit &eingabe[0])
den gesamten String übernehmen konnten.
Um diesen Zusammenhang vollständig zu
verstehen, wiederholen wir das Ganze in gleicher Form mit einem Integer-Array.
// Programm array005.cpp
#include
<iostream>
int main()
|
Hier meldet der Compiler bei cin>>eingabe
eine
"Illegal structur operation" oder
(MSVC++) "error C2679: Binaerer Operator '>>'
:
Kein Operator definiert, der einen rechtsseitigen
Operator vom Typ 'int [80]' akzeptiert (oder keine geeignete Konvertierung
moeglich)."
Da wir wissen, dass eingabe die Kurzform
für &eingabe[0] ist, tauschen wir dies aus und erhalten:
// Programm array006.cpp
...
cin >> &eingabe[0];
...
Auch hier meldet der Compiler an der Stelle
cin>>eingabe eine "Illegal structur operation".
Dies ist beruhigend, da wir ja nur den gleichwertigen
Programm-Code angewandt haben.
Nun wird es klarer: Die Fähigkeit von cin
(oder scanf in C), einen String unter Angabe
einer Adresse der Reihe nach als Character-Variablen
in ein Array des Typs char einzulesen,
ist etwas besonderes, aber leider nicht von
glasklarer Logik geprägt.
Da wir jetzt endlich Adressen sehen möchten,
streichen wir den Adress-Operator und geben
separat die ersten drei Elemente des Arrays ein:
// Programm array007.cpp
#include
<iostream>
int main()
|
Wenn Sie jetzt z.B. drei Integer-Zahlen eingeben,
dann werden links die Speicheradressen und
rechts daneben die zuvor eingegebenen Zahlen
auf dem Bildschirm dargestellt
(die Speicheradressen können bei Ihnen
natürlich andere sein):
0x0066FCB4
333
0x0066FCB8
444
0x0066FCBC
555
Der Speicherbedarf für int beträgt bei modernen Compilern 4 Byte (32 bit), bei älteren Compilern 2 Byte (16 bit).
Beachten Sie bitte, dass wir einiges
verändert haben, um ein vernünftiges Programm zu erhalten.
Insbesondere haben wir die Zahlen einzeln nacheinander
abgefragt (kein String),
und der Abbruch-Trick unter Prüfung des
Elementes auf '\0' in der for-Schleife ist hier sinnlos.
Wir sind bewusst den Weg vom String im
Character-Array zu Zahlen im Integer-Array gegangen, damit deutlich wird,
dass Besonderheiten bei der String-Ein-
und -Ausgabe in Verbindung mit & und *& bestehen.
Leider gehen diese bezüglich des Adress-Operators
auf Kosten der Logik.
Zunächst verbleiben wir in der Welt der
Zahlen und experimentieren mit dem Inhalts-Operator,
indem wir eingabe[i] durch *&eingabe[i] ersetzen.
Zusätzlich geben wir aus Neugier einfach drei weitere
Speicherplätze des Arrays aus, die wir
nicht selbst vorher mit Zahlen beschicken:
// Programm array008.cpp
#include
<iostream>
int main()
|
Hier funktioniert der Adress-Operator wie
erwartet. Er gibt die Speicheradresse der Elemente eingabe[i] aus.
Insbesondere sehen wir an den Abständen
zwischen den Hexadezimal-Adressen, dass eine short-Integer-Variable 2
Bytes Speicherplatz benötigt.
Jetzt steigen wir um auf float-Variablen und
sehen, dass solcheVariablen 4 Bytes belegen. Zusätzlich prüfen
wir noch einmal bezüglich
*&eingabe[i] und eingabe[i] auf Übereinstimmung.
Geben Sie bitte Zahlen mit mehr als 6 Stellen nach dem Komma ein,
um die deutlich höhere Genauigkeit von
double im Vergleich zu float zu erkennen:
// Programm array009.cpp
#include
<iostream>
int main()
|
Nehmen Sie sofort die Gelegenheit wahr und testen auch double (8 Byte) auf Speicherplatzbedarf und Genauigkeit.
Nachdem wir gesehen haben, dass C++ im
Zahlenbereich bezüglich des Adress-Operators wie erwartet reagiert,
kehren wir zu den Strings zurück. Hier
besteht nach wie vor die Aufgabe, Speicheradressen einzelner Elemente eines
Strings
am Bildschirm auszugeben. Wir gehen von Programm
array004 aus und wandeln die Adresse &eingabe[i] vor der Ausgabe
in einen Zahlenwert des Typs long um:
//Programm array010
#include
<iostream>
int main()
|
Wie man sieht, haben wir jetzt das Ziel erreicht, die Speicheradressen der einzelnen Zeichen auszugeben. Als nächstes ändern Sie bitte long in double ab. Der Compiler meldet jetzt z.B.: "Cannot cast from 'char*' to 'double'." Um sicher zu gehen, dass es sich hier um eine Besonderheit bei Strings handelt, kehren wir zu Programm array008 zurück und wandeln auch hier die Adressangabe in das Long-Integer-Format um (Programm array011). Die Ausgabe der Speicheradressen erfolgt wie erwartet im Dezimalzahlen-Format.
Jetzt ändern wir auf double ab und erhalten
z.B. eine ähnliche Compiler-Meldung: "Cannot cast from 'int*' to 'double'."
// Programm array011.cpp
#include
<iostream>
int main()
|
Gehen Sie Compiler-Meldungen immer auf den
Grund, denn aus Fehlern lernt man. Der Compiler hat uns mitgeteilt,
dass der Ausdruck &eingabe[i] bei Strings
vom Typ char* und bei Zahlen vom Typ int* ist.
Nun werden wir erforschen, was char* und int* beschreibt und warum es bei der Ausgabe mit cout verschieden reagiert?
Nach den obigen Versuchen mit Arrays und Strings kommen wir folgerichtig zu den Zeigern. Arrays, Strings und Zeiger (Pointer) sind in C++ eng miteinander verknüpft. Daher betreten wir jetzt dieses interessante Gebiet der Zeiger, das für viele leider abschreckend wirkt.
Zuvor fassen wir kurz zusammen:
Bisher experimentierten wir mit einzelnen
Array-Elementen eingabe[i], den zugehörigen Speicheradressen &eingabe[i]
(Besonderheit: eingabe ist &eingabe[0])
und den Inhalten an den Speicheradressen *&eingabe[i].
Wir fanden, dass man bei Elementen in
Strings die Ausgabe der Speicheradressen durch Umwandlung in eine Integer-Variable
erreicht. Bei Ausgabe der "nackten" Adresse wurde nicht die Adresse, sondern
der restliche String ab dieser Adresse ausgegeben
(interessant, aber zunächst nicht beabsichtigt
und evtl. noch nicht völlig verstanden).
Um Zeigervariablen von anderen Variablen schnell
unterscheiden zu können, ist es üblich,
die Namen solcher Zeiger zur Unterscheidung mit
einem kleinen p (pointer) zu beginnen.
C++ schafft bei der Deklaration der Zeiger
leider Verwirrung: Als Kennzeichen einer Zeigervariable wird * vor dem Namen
eingesetzt.
Dieses Zeichen wird bereits als Inhalts-Operator
verwendet. Zusätzlich ist * auch das Zeichen für die Multiplikation.
Hier hilft nur Übung und Gewöhnung.
Als Typ des Zeigers deklariert man den Typ
der Array-Elemente, auf die er zeigt.
Nachfolgend finden Sie ein Beispiel (ausgehend
von Programm array008),
in dem Speicheradressen in der for-Schleife einem
Zeiger zugewiesen werden:
What is a pointer?
A pointer is a variable that holds the memory address of another
variable.
To quickly distinguish pointer variables from other variables, it is
common practice to prefix the names of such pointers with a small letter p (for
"pointer"). Unfortunately, C++ can be confusing when declaring pointers: as an
indicator of a pointer variable, the * symbol is used before the variable name.
This symbol is already used as the content operator, and it is also used as the
multiplication operator. The only solution to this confusion is practice and
habituation. The type of the pointer is declared as the type of the array
elements to which it points. Below is an example (based on program array008), in
which memory addresses are assigned to a pointer in a for-loop:
// Programm array012.cpp
#include
<iostream>
int main()
|
Das nächste Programm demonstriert uns
die Besonderheit der Pointerarithmetik:
Erhöht man den Zeigerinhalt um 1, z.B.
mit p_eingabe = p_eingabe + 1 oder mit p_eingabe++,
dann wird die Speicheradresse nicht um eins
erhöht, sondern um die Zahl, die dem Variablen-Speicherbedarf entspricht,
also hier bei int um 4 Byte. Man rückt den
Zeiger in einem Array sozusagen von Wert zu Wert weiter.
Solche Fähigkeiten sind für den Gebrauch
in Schleifen nützlich.
Wir werden dies im nächsten Programm
sofort austesten:
// Programm array013.cpp
#include
<iostream>
int main()
|
Im vorstehenden Programm arbeitet p_eingabe
stellvertretend für das bisherige &eingabe[i].
Durch Aufnahme von p_eingabe++ in die for-Anweisung
wird der Zeiger jeweils um einen Wert
("Variablenbreite", z.B. 2 Bytes bei short oder
4 Bytes bei float etc.) weitergerückt.
*p_eingabe gibt uns den Inhalt der
Variable, die an dieser Speicherstelle beginnt.
Als Zeiger beinhaltet p_eingabe
diese Adresse.
Experimentieren Sie an dieser Stelle mit der
Pointerarithmetik,
indem Sie short durch float etc. ersetzen:
In the previous program, p_eingabe works as a replacement for the previous
&eingabe[i]. By including p_eingabe++ in the for loop, the pointer is advanced
by one value ("variable width", e.g. 2 bytes for short or 4 bytes for float,
etc.) at a time. *p_eingabe gives us the contents of the variable that begins at
this memory location. As a pointer, p_eingabe contains this address. Experiment
with pointer arithmetic at this point by replacing short with float, etc.:
// Programm array014.cpp
...
float eingabe[80];
float *p_eingabe;
...
Da wir den Zusammenhang zwischen Zeiger und
Adresse nun kennen,
probieren wir dies sofort an unserem interessanten
Beispiel mit einem String aus:
As we now understand the relationship between pointers and addresses, let's try
it out on our interesting example with a string:
// Programm array015.cpp
#include
<iostream>
int main()
|
Wir stellen fest, dass *p_eingabe analog
zu *&eingabe[i] arbeitet.
Was passiert, wenn wir das Zeichen * weglassen
und damit den Zeiger direkt ausgeben?
// Programm array016.cpp
...
cout << p_eingabe;
...
Dies ergibt das von den Strings bekannte Bild:
p_eingabe+i funktioniert hier also analog
zu &eingabe[i] und gibt den gesamten String beginnend ab der im
Zeiger befindlichen Adresse aus.
In unserem Experimentierfeld mit Arrays, Strings,
Adressen, Inhalten und Zeigern halten wir kurz inne und betrachten im Überblick
folgende Gleichwertigkeiten von Ausdrücken
bezüglich Adressen und Zeigern
(p_eingabe soll hierbei durch Zuweisung die
Startadresse des Arrays enthalten):
&eingabe[0]
eingabe p_eingabe &p_eingabe[0] Startadresse = Adresse des Elementes 0
|
&eingabe[i]
eingabe+i p_eingabe+i &p_eingabe[i] Startadresse = Adresse des Elementes i
|
Durch die Vielfalt sieht das Ganze verwirrend aus. Nehmen wir dies Schritt für Schritt unter die Lupe, um die Regeln zu verstehen:
Betrachten wir zunächst die Äquivalenz folgender Paarungen von Ausdrücken:
eingabe + i <---> p_eingabe + i
&eingabe[i] <---> &p_eingabe[i]
Die erste Zeile zeigt die Äquivalenz
zwischen Adresse und Zeiger, die wir bereits verwendet haben.
Wichtig ist diesbezüglich die spezielle
Pointerarithmetik: Adressen oder Zeiger werden entsprechend der "Variablenbreite"
im Speicher bewegt. Der Ausdruck p_eingabe+5 bedeutet somit, dass der
Zeiger von der Adresse des "ersten Kästchens" (Element[0]) auf die Adresse
des "sechsten Kästchens" (Element[5]) weiterrückt. Gewöhnungsbedürftig
ist, dass der Name eines (eindimensionalen) Arrays gleichzeitig
als Adresse von Element[0] verwendet wird. Durch Wegfall des Adress-Operators
oder des Hinweises auf einen Zeiger (nur gegeben, wenn Sie p... im Namen
verwenden) erscheint der einfache Array-Name wie eine gewöhnliche Variable.
Dass eingabe identisch mit &eingabe[0]
ist, wissen Sie bereits.
Allgemein gilt:
In general:Array + i <---> &Array[i]
Infolge der obigen Regel gilt unter Verwendung des Inhalts-Operators bzw. unter Weglassen des Adress-Operators:
*(Array+i) <--->
Array[i]
Nur der Vollständigkeit halber sei hier
angemerkt, dass über die Kette
For completeness' sake, it should be noted that through the chain:
Array[i]
<---> *(Array+i) <---> *(i+Array) <---> i[Array]
folglich auch Array[i] und i[Array] gleichwertig sind, wenn dies beim direkten
Betrachten auch nicht verständlich ist.
Der Compiler schluckt dies kommentarlos, während
beim Betrachter
teilweise ernsthafte Verständnisprobleme
entstehen.
Auf der Ebene der Array-Elemente, am Beispiel
eingabe[80], gilt daher folgende Gleichwertigkeit der Begriffe:
eingabe[0]
*(eingabe) *(p_eingabe) p_eingabe[0] Startelement = Element 0 |
eingabe[i]
*(eingabe+i) *(p_eingabe+i) p_eingabe[i] Startelement = Element i |
Nun wollen wir das Ganze in einem Programm
vergleichend testen. Das nachfolgende Programm definiert ein double-Array
mit sechs Zahlen und ein char-Array mit dem String "Jahr". Anschließend
werden sämtliche Begriffe angewendet, um die jeweiligen Wirkungen und
die gleichartigen Verhaltensweisen zu überprüfen:
Now we want to test everything in a program for comparison. The following
program defines a double array with six numbers and a char array with the string
"Jahr". Then, all the terms are applied to check their respective effects and
similar behaviors:
// Programm array017.cpp
#include
<iostream>
int main()
zahl[0]= 333.333;
for ( i=0; i<=5; i++ ) cout << "\1 " << "Kurze Pause" <<" \1";
for ( j=0; j<80000000; j++ ); // Leere Warteschleife
cout << "\n";
for ( i=0; i<=3; i++ ) |
Nachdem das vorstehende Programm die Wirkung
der verschiedenen Programmcodes für Array-Elemente und Array-Zeiger
sowohl für Zahlen als auch für einen
String gezeigt hat, sollten Sie selbst mit diesem Programm ein wenig experimentieren:
Ändern Sie z.B. die Deklaration des Zahlenarrays
von 'double zahl[6];' auf 'double zahl[5]' ab und beobachten Sie, was nach
dem Start passiert.
Der Compiler akzeptiert diese zu enge Festlegung
(nur fünf anstelle sechs Zahlen) problemlos. Bei verschiedenen PC-Konstellation
kann es hier beim Programm-Start zu einem Systemabbruch kommen. Ein manchmal
schwierig zu findender Fehler (Kleine Ursache - große Wirkung). Achten
Sie bei eigenen Programmen daher immer darauf, dass bei der Deklaration
eines Arrays die Zahl der Elemente ausreichend ist, um alle Werte aufzunehmen.
Spielen Sie mit der Warteschleife:
Ändern Sie 'long j;' in 'short j;' ab.
Was geschieht? Die Pause hört nicht mehr auf!
Sie haben eine Endlosschleife geschaffen, da
man im short-Bereich (-32768 ... 32767) nicht bis auf 80000000 zählen
kann!
Die Zahl 80000000 wurde ursprünglich für
einen 486er mit 50 MHz entworfen. Sollte ihr Rechner schneller sein, was
ich für Sie hoffe,
erhöhen Sie die Zahl (natürlich mit
'long j;'). Sollten Sie 2147483647 überschreiten, so drehen Sie erneut
in einer Endlosschleife.
Geben Sie die Adressen der sechs Zahlenwerte im Hexadezimal-Format aus.
Ändern Sie von double auf float ab, und untersuchen Sie die Auswirkungen bei mehr als sechs Nachkommastellen.
Schreiben Sie das Programm so um, dass Sie sechs verschiedene Zahlen selbst eingeben können (for-Schleife / cin).
Im Ausgabe-Teil der Zeiger und Elemente gibt
es sehr viele Spielarten. Setzen Sie hier nach Belieben * und & hinzu
und beobachten Sie die Wirkung auf den Compiler
oder das Programm.
Sie könnten auch Typ-Umwandlungen vornehmen
(z.B. char --->
int, String als ASCII-Code ausgeben).
Viel Spaß weiterhin mit Arrays und Zeigern.