Verständnisfrage char arrays
-
ich arbeite grad einen Kurs durch und versteh etwas mit den char arrays nicht.
als Bsp definiere ich ein char-array:char text[] = "Beispiel";was mir klar ist, das ein array mit chars angelegt wird, hier also 9 Felder wovon jedes 1 Byte belegt.
Was mir nicht klar ist wieso man im gegensatz zu int-Feldern bei der Ausgabecout << text;das gesamte Feld ausgegeben bekommt. Bei den int-Feldern bekommt man die Adresse des ersten Felds. Wobei mir das auch nicht so klar ist, da man ja sont den Adressoperator & verwendet. Gibt man nur den Feldnamen an handelt es sich dabei wohl um ein Pointer auf das erste Feld. Bei Chararrays ist das wohl wieder anders.
-
Arrays können implizit zu Zeigern auf das erste Element konvertiert werden ("array to pointer decay"). Deshalb braucht man den Adressoperator nicht, um eine Adresse auf den Anfang zu erhalten.
int array[7]; int* p1 = &array[0]; int* p2 = array; // äquivalentIm Weiteren ist der
operator<<der Streams überladen für Zeiger aufchar. Hier wird also wiederum das Array zum Zeiger umgewandelt. Dass das nur fürchar- und nicht fürint-Zeiger gilt, liegt daran, dass fürint*keine Überladung existiert, sondern nur fürvoid*, also typenlose Zeiger, oder ebenchar*. Wenn du jetzt einenint*mittels<<in den Stream schiebst, kommt es zu einer (wieder impliziten) Umwandlung zuvoid*, die entsprechende Operatorüberladung wird aufgerufen und die Adresse desintausgegeben.
-
rudpower schrieb:
... handelt es sich dabei wohl um ein Pointer auf das erste Feld. Bei Chararrays ist das wohl wieder anders.
Dein 'text' ist ein Pointer auf das erste Element des Arrays.
-
Desweiteren sind Char-Arrays 0-terminiert, weswegen er das auch ausgeben kann, denn er kann so testen wie lang das Array ist. Bei einem int-Array ist das nicht der Fall.
Kannst ja mal "lustig" sein und folgendes probieren:
char text[] = "Beispiel"; test[8] = 'x'; cout << text;
-
Operatorüberladung ist neu für mich, ich kenne nur Funktionsüberladung
-
Operatoren sind auch nur (meist sehr simple inline) Funktionen.

-
Fellhuhn schrieb:
Desweiteren sind Char-Arrays 0-terminiert, weswegen er das auch ausgeben kann, denn er kann so testen wie lang das Array ist. Bei einem int-Array ist das nicht der Fall.
Kannst ja mal "lustig" sein und folgendes probieren:
char text[] = "Beispiel"; test[8] = 'x'; cout << text;
dann wird die 0 überschrieben und er schreibt Beispielx und nicht definierte Zeichen da die 0 fehlt.
-
Nexus schrieb:
Arrays können implizit zu Zeigern auf das erste Element konvertiert werden ("array to pointer decay")
wieso "können". ich dacht es sind schon Pointer?
-
Richtig. Deswegen gibt es keinen entsprechenden Operator für beliebige Arrays. Ist halt eine Sonderheit der char-Arrays.
-
Fellhuhn schrieb:
Richtig.
Falsch. Arrays sind keine Zeiger. Und das ist auch trivial: schließlich kann ein einzelner Zeiger unmöglich eine beliebig große Anzahl beliebiger Objekte speichern.
-
camper schrieb:
Fellhuhn schrieb:
Richtig.
Falsch. Arrays sind keine Zeiger. Und das ist auch trivial: schließlich kann ein einzelner Zeiger unmöglich eine beliebig große Anzahl beliebiger Objekte speichern.
Was ich schrieb bezog sich auf das einen davor.

Seinen Beitrag hatte ich gar nicht gelesen, musste ja dank "Sie können einen Beitrag nicht so schnell nach Ihrem letzten absenden, bitte warten Sie einen Augenblick." ewig warten...
-
Fellhuhn schrieb:
camper schrieb:
Fellhuhn schrieb:
Richtig.
Falsch. Arrays sind keine Zeiger. Und das ist auch trivial: schließlich kann ein einzelner Zeiger unmöglich eine beliebig große Anzahl beliebiger Objekte speichern.
Was ich schrieb bezog sich auf das einen davor.

Seinen Beitrag hatte ich gar nicht gelesen, musste ja dank "Sie können einen Beitrag nicht so schnell nach Ihrem letzten absenden, bitte warten Sie einen Augenblick." ewig warten...
Oh, übersehen. Ok, so wird wenigstens niemand anderes verwirrt.
-
Hier wird also wiederum das Array zum Zeiger umgewandelt. Dass das nur für
char- und nicht fürint-Zeiger gilt, liegt daran, dass fürint*keine Überladung existiert, sondern nur fürvoid*, also typenlose Zeiger, oder ebenchar*. Wenn du jetzt einenint*mittels<<in den Stream schiebst, kommt es zu einer (wieder impliziten) Umwandlung zuvoid*, die entsprechende Operatorüberladung wird aufgerufen und die Adresse desintausgegeben.dies versteh ich wiederum nicht

-
Ganz einfach, es gibt für Zeige im ostream nur zwei <<-Operatoren Definitionen:
einmal für void* bei denen der Wert des Zeigers, also die Speicheradresse, ausgegeben wird
einmal für char* bei denen der String ausgegeben wird, bis zur 0.Wenn du nun cout << xxx; aufrufst, wird geschaut ob xxx vom Typ char* ist. Ist dies der Fall wird der zweite Operator oben ausgeführt, bei allen anderen Zeigern erfolgt die Umwandlung zum void* und somit der erste Operator.
-
also steht dort ein char* wird die Zeichenkette bis zur 0 ausgegeben und steht dort ein anderer Zeiger wie int* wird die Adresse ausgegeben die in dem Zeiger steht.
-
Richtig.
Kannst ja testweise mal deinen char-Array für die Ausgabe zum int-Zeiger casten:
cout << (int*)meinArray;
Dann sollte er die Adresse ausgeben.
-
cout << &meinArray;müsste ja das gleiche Ausgeben, also die Adresse des erstes Feldes.
Wie komm ich eigentlich an die zweite Adresse? doch übercout << (int*)meinArray+1;Das kann aber nicht stimmen, denn wenn ich &meinArray+1 schreibe bekomm ich eine andere Adresse obwohl das ja eigentlich äquivalent ist oder?
als Bsp:char teste[] = "mytest"; char* ptr_test = teste; cout << (int*)ptr_test << " " << ptr_test << " " << &teste << endl; /*cout << (int*)ptr_test+1 << endl;*/ //Ausgabe: 0012FF40 cout << &ptr_test+1 << endl; //Ausgabe: 0012FF38alles sehr merkwürdig. wollt so auch nachvollziehen was auf dem stack passiert aber jetzt versteh ich gar nix mehr

Normalerweise müsste doch zwischen den Adressen ein Byte liegen, da ja char 1 Byte speichern kann.
-
rudpower schrieb:
Operatorüberladung ist neu für mich, ich kenne nur Funktionsüberladung
Man kann auch Operatoren überladen, nur das brauchst du hier nicht. Character-Arrays sind ANSI-C - sie brauchen das abschliessende Nullzeichen. Wir haben hier immer wieder Verständnisprobleme, weil ANSI-C seit C++ (hier oft geäussert) auf den Schrott gehören soll.
-
Das liegt das wenn du einen Pointer inkrementierst er immer so weit vorspringt wie groß das Element ist. Und ein char ist kleiner als ein int.

-
char teste[] = "mytest"; char* ptr_test = teste; cout << (int*)ptr_test << " " << ptr_test << " " << &teste << endl; //Ausgabe: 0012FF58 mytest 0012FF58 cout << (int*)ptr_test+1 << endl; //Ausgabe: 0012FF5C cout << &ptr_test+1 << endl; //Ausgabe: 0012FF50dann müsste ja die nächste Adresse 0012FF59 sein, da ja ein char 1 Byte belegt.