Angesichts der Erklärungen
char *s0 = "hello world";
char s1[] = "hello world";
nehmen Sie die folgende hypothetische Speicherzuordnung an (die Spalten stehen für Zeichen an den Offsets 0 bis 3 von der gegebenen Zeilenadresse, also z. B. die 0x00
in der rechten unteren Ecke ist unter der Adresse 0x0001000C + 3
= 0x0001000F
):
+0 +1 +2 +3
0x00008000: 'h' 'e' 'l' 'l'
0x00008004: 'o' ' ' 'w' 'o'
0x00008008: 'r' 'l' 'd' 0x00
...
s0: 0x00010000: 0x00 0x00 0x80 0x00
s1: 0x00010004: 'h' 'e' 'l' 'l'
0x00010008: 'o' ' ' 'w' 'o'
0x0001000C: 'r' 'l' 'd' 0x00
Das String-Literal "hello world"
ist eine 12-Elemente-Anordnung von char
( const char
in C++) mit statischer Speicherdauer, was bedeutet, dass der Speicher dafür beim Programmstart zugewiesen wird und bis zur Beendigung des Programms zugewiesen bleibt. Der Versuch, den Inhalt eines String-Literal zu ändern, führt zu undefiniertem Verhalten.
Die Linie
char *s0 = "hello world";
definiert s0
als Zeiger auf char
mit automatischer Speicherdauer (d.h. die Variable s0
nur für den Bereich existiert, in dem es deklariert ist) und kopiert die Adresse des String-Literales ( 0x00008000
in diesem Beispiel) zu. Beachten Sie, dass seit s0
auf ein String-Literal zeigt, sollte es nicht als Argument für eine Funktion verwendet werden, die versuchen würde, es zu verändern (z. B., strtok()
, strcat()
, strcpy()
, usw.).
Die Linie
char s1[] = "hello world";
definiert s1
als 12-Element-Array von char
(Länge wird aus dem Stringliteral übernommen) mit automatischer Speicherdauer und kopiert die Inhalt des Literales in das Array. Wie Sie aus der Speicherabbildung ersehen können, haben wir zwei Kopien der Zeichenkette "hello world"
Der Unterschied besteht darin, dass Sie die Zeichenkette ändern können, die in s1
.
s0
y s1
sind in den meisten Kontexten austauschbar; hier gibt es Ausnahmen:
sizeof s0 == sizeof (char*)
sizeof s1 == 12
type of &s0 == char **
type of &s1 == char (*)[12] // pointer to a 12-element array of char
Sie können die Variable neu zuordnen s0
auf ein anderes Zeichenfolgenliteral oder eine andere Variable verweisen. Sie können die Variable nicht neu zuweisen s1
auf ein anderes Array verweisen.