C Stil Strings, Zeiger, Arrays

8

Ich habe Probleme zu verstehen, was eine C-Style-Zeichenfolge ist. Glückliches frühes neues Jahr

Was ich weiß: Ein Zeiger enthält eine Speicheradresse. Dereferenzieren des Zeigers gibt Ihnen die Daten an diesem Speicherort.

%Vor%

Nun zu dem, was ich nicht verstehe (indem ich das, was oben ist, als Quelle für meine Verwirrung benutze): Es gibt mehrere Möglichkeiten, Strings zu deklarieren. Ich lerne C ++, aber Sie können auch C-Stil-Strings verwenden (gut zu verstehen, obwohl C ++ - Strings unterlegen)

C ++:

%Vor%

C-Stil:

%Vor%

Version3 ist, wo ich Probleme habe. Hier gibt es einen Zeiger auf ein Zeichen. Ich weiß, dass ein Array-Name ein Zeiger auf das erste Element in einem Array ist.

%Vor%

Vorher, in dem Abschnitt "was ich wusste", würde das Ausdrucken des Namens eines Zeigers die Adresse ausgeben, die er enthielt. Hier wird beim Ausdrucken des Namens eines Zeigers die gesamte Zeichenfolge ausgegeben. Sagen die doppelten Anführungszeichen um "Hallo Sie" irgendwie dem Programm: "hey Ich weiß, dass Sie ein Zeiger sind, und Sie werden auf die Position von 'H' initialisiert, aber da ich diese doppelten Anführungszeichen sehe, überspringen Sie 1 Byte in Speicherposition und alles ausdrucken, was Sie sehen, bis Sie ein \ 0 erreichen "(1-Byte-Bewegung, da Zeichen 1 Byte groß sind).

Wie kommt es, dass beim Ausdrucken eines Zeigers eine Zeichenkette ausgegeben wird? Vor dem Ausdrucken eines Zeigernamens wurde die Speicheradresse ausgedruckt, auf die sie initialisiert wurde.

Bearbeiten: Exportiert cout << &version3 die Position von 'H' oder die Position des Zeigers, version3 , die die Speicheradresse von 'H' enthält?

    
DWade64 31.12.2013, 18:46
quelle

3 Antworten

7

Das Ausdrucken von char* mit cout funktioniert anders als das Drucken, z. B. int* mit cout . Aus Gründen der Kompatibilität mit C-Style-Strings behandelt die überladene Version von << , die ein char* -Argument verwendet, das char* als C-Style-String. Wenn Sie die Speicheradresse drucken möchten, die ein char* enthält, können Sie sie in void* umwandeln.

Ja, wenn Sie eines von

schreiben %Vor%

Ein NUL ( s1 ) Terminator wird für Sie am Ende der Zeichenfolge hinzugefügt. Der Unterschied zwischen diesen beiden ist, dass s2 ein Zeiger auf ein String-Literal ist, dessen Inhalt man gemäß dem C-Standard nicht ändern darf, während "hi haha" ein Array ist. Das heißt, ein Speicherblock, der für Sie auf dem Stack reserviert ist, der initialisiert ist, um den Wert char s[3] = "abc"; zu speichern, und Sie können den Inhalt beliebig ändern. Die Menge an Speicher, die für das Array reserviert ist, ist genau genug, um die Zeichenfolge, die als Initialisierer verwendet wird, zu halten, und wird automatisch für Sie bestimmt, weshalb die eckigen Klammern leer sein können.

Eine Anmerkung: Wenn Sie in C s eingeben, wird {'a', 'b', 'c'} auf char *s = "..." initialisiert, ohne einen NUL-Terminator! Dies liegt an einer Klausel im Standard, die besagt, dass Strings in diesem Kontext mit einem NUL-Terminator initialisiert werden, wenn im Array Platz ist (oder eine ähnliche Formulierung). In C ++ ist dies nicht der Fall. Weitere Informationen finden Sie unter Kein Compiler Fehler, wenn Char-Array mit fester Größe initialisiert wird, ohne genügend Platz für Null-Terminator zu haben .

Bearbeiten als Antwort auf Ihre Frage: Wenn Sie cout << &s; und you s haben, wird die Adresse mit dem -Zeiger gedruckt s wird gespeichert und nicht die Adresse, die s enthält (die Adresse des ersten Elements der Zeichenfolge, auf die sich %code% bezieht).

    
Andrey Mishchenko 31.12.2013, 18:51
quelle
5
  

Ich weiß, dass ein Array-Name ein Zeiger auf das erste Element in einem Array ist.

Nein, ist es nicht. Es wird nur implizit in die eine konvertiert (in den meisten Fällen).

  

Sagen Sie die doppelten Anführungszeichen um "Hallo Sie" irgendwie dem Programm: "hey Ich weiß, dass Sie ein Zeiger sind, und Sie werden auf die Position von 'H' initialisiert, aber da ich diese doppelten Anführungszeichen sehe, überspringen Sie 1 Byte im Speicherbereich und Ausdruck alles was Sie sehen, bis Sie ein \ 0 "?

erreichen

Nein, tun sie nicht. Es kommt auf den Typ an.

std::ostream::operator<< hat eine Überladung für einen generischen Zeiger ( void * ) und eine Überladung für const char * . Wenn Sie also cout << "some char array or pointer"; schreiben, wird diese Überladung und nicht die für andere Zeigertypen aufgerufen. Diese Überladung verhält sich anders: Anstatt den numerischen Wert des Zeigers auszugeben, druckt sie alles bis zu einem NUL-Terminator aus.

    
user529758 31.12.2013 19:09
quelle
3

Sie stellen hier zwei Fragen, von denen eine allgemeiner ist und die ich zuerst beantworten werde.

Ein Zeiger ist ein "Handle" (eine Adresse) für eine Position im Speicher. Der Inhalt dieses Ortes ist ein Wert. Wie dieser Wert interpretiert wird, hängt vom Typ des Zeigers ab. Stellen Sie es sich so vor: Eine Adresse ist der Standort eines Hauses, zum Beispiel 10 Main Street. Der Inhalt von 10 Main Street ist der Inhalt des Hauses unter dieser Adresse. In C (und C ++) ausgedrückt:

%Vor%

Ist eine Variable, die die Adresse einer Ganzzahl enthalten kann.

%Vor%

Ist eine Variable, die eine Ganzzahl ist.

%Vor%

Hat p 'auf' x zeigen, indem in p die ADRESSE von x gespeichert wird.

%Vor%

Speichert in x den Wert 10.

%Vor%

Weil * p sagt, dass man den Inhalt von p 'als Wert verwenden und dann mit x vergleichen soll.

%Vor%

Weil & amp; x sagt, 'die Adresse von x' als einen Wert zu verwenden und es dann mit p zu vergleichen, was eine Variable vom Typ Zeiger ist.

Eine Zeichenfolge, die eine Folge von null oder mehr Zeichen ist, wird in C (und C ++) durch die Zeichen "und" dargestellt. Im Speicher werden diese Werte fortlaufend gespeichert und automatisch durch ein abschließendes Null-Byte beendet, das ein Byte mit dem Wert 0 ist. Die Zeichenfolge "Hello, world!" wird gespeichert, vorausgesetzt, Sie verwenden eine 8-Bit-ASCII-Zeichencodierung wie:

65 101 108 108 111 44 ​​32 87 111 114 108 33 0

Sie können dies anhand des folgenden Code-Snippets selbst sehen:

%Vor%

Da der Nullwert (Nullbyte) vom Compiler automatisch zu einer konstanten Zeichenkette hinzugefügt wird, haben die folgenden zwei Arrays die gleiche Größe:

%Vor%

Einfach gesagt, ist eine 'C-Stil-Zeichenfolge' einfach eine Reihe von Zeichen, die durch eine Null abgeschlossen sind, die Ihre erste Frage beantwortet.

    
Carey Gister 31.12.2013 19:34
quelle

Tags und Links