Ich habe kürzlich C++ gelernt und festgestellt, dass Zeichenfolgenliterale in C++ Konstanten sein müssen, während dies in C nicht der Fall ist. Hier ist ein Beispiel. Der folgende Code wäre in C gültig, aber nicht in C++:
char* str = "Hello World";
Um dasselbe in C++ zu tun, muss die folgende Anweisung verwendet werden:
const char* str = "Hello World";
Könnte jemand erklären warum?
Erweitern Sie die Antwort von Christian Gibbons ein wenig …
In C werden Zeichenfolgenliterale wie "Hello World"
werden in Arrays von gespeichert char
so dass sie während der gesamten Lebensdauer des Programms sichtbar sind. String-Literale sind soll unveränderlich sein, und einige Implementierungen speichern sie in einem Nur-Lese-Speichersegment (so dass der Versuch, den Inhalt des Literals zu ändern, einen Laufzeitfehler auslöst). Einige Implementierungen tun dies nicht, und der Versuch, den Inhalt des Literals zu ändern, löst möglicherweise keinen Laufzeitfehler aus (es scheint sogar wie beabsichtigt zu funktionieren). Die C-Sprachdefinition lässt das Verhalten “undefiniert”, so dass der Compiler die Situation frei handhaben kann, wie er es für richtig hält.
In C++ werden String-Literale in Arrays von gespeichert const char
sodass jeder Versuch, den Inhalt des Literals zu ändern, eine Diagnose auslöst zur Kompilierzeit.
Wie Christian betont, die const
Das Schlüsselwort war ursprünglich kein Teil von C. Es war jedoch ursprünglich Teil von C++ und macht die Verwendung von Zeichenfolgenliteralen ein wenig sicherer.
Denken Sie daran, dass die const
Stichwort nicht bedeutet “speichere dies im Nur-Lese-Speicher”, es bedeutet nur “dieses Ding darf nicht das Ziel einer Zuweisung sein”.
Denken Sie auch daran, es sei denn, es handelt sich um den Operanden von sizeof
oder unär *
Operatoren oder ist ein Zeichenfolgenliteral, das zum Initialisieren eines Zeichenarrays in einer Deklaration verwendet wird, an Ausdruck vom Typ “N-elementiges Array von T
” wird in einen Ausdruck vom Typ “Zeiger auf T
” und der Wert des Ausdrucks ist die Adresse des ersten Elements des Arrays.
In C++ beim Schreiben
const char *str = "Hello, world";
das die Anschrift des ersten Zeichens der Zeichenfolge gespeichert wird str
. Sie können einstellen str
auf a zeigen anders String-Literal:
str = "Goodbye cruel world";
aber was du kann nicht ändern Sie den Inhalt der Zeichenfolge, so etwas wie
str[0] = 'h';
oder
strcpy( str, "Something else" );
C hatte anfangs nicht die const
Schlüsselwort, so dass es Legacy-Code beschädigen würde, wenn sie Literale in erforderlich ändern würden const
-Qualifikation nach Einführung des Schlüsselwortes. Die Zeichenfolgenliterale von C sind jedoch unveränderlich, sodass das Ändern des Inhalts ein undefiniertes Verhalten ist, selbst wenn dies nicht der Fall ist const
-qualifiziert.
C++ hingegen wurde mit dem entworfen const
Stichwort. Anfänglich erlaubte C++ die Zuweisung von String-Literalen zu non const
-qualifiziert char *
s vermutlich aus Gründen der Kompatibilität mit vorhandenem C-Code. Ab dem C++03-Standard haben sie sich jedoch entschieden, diese Funktionalität zu verwerfen, anstatt zuzulassen, dass die Dissonanz für immer andauert. Ich würde schätzen, wie viel Legacy-C++-Code auf Nicht-const
qualifiziert char *
s zeigt auf String-Literale, dass sie klein genug sind, dass es ein würdiger Kompromiss wäre.
” während sie es in C nicht tun” Sie sind falsch. String-Literale in C sind konstant, aber a darf auf sie zeigen
char*
. Sie können die Zeichenfolge immer noch nicht über diesen Zeiger ändern. In C++ haben sie diese Ausnahme einfach eliminiert, um die Korrektheit zu erhalten, um Verwirrung und Fehler zu vermeiden.– Francois Andrieux
4. Mai 2020 um 21:26 Uhr
Denn so haben sie die Sprache entworfen. C hatte anfangs nicht die
const
Schlüsselwort, so dass es Legacy-Code beschädigen würde, wenn sie Literale in erforderlich ändern würdenconst
-Qualifikation nach Einführung des Schlüsselwortes. Die Zeichenfolgenliterale von C sind jedoch unveränderlich, sodass das Ändern des Inhalts ein undefiniertes Verhalten ist, selbst wenn dies nicht der Fall istconst
-qualifiziert.– Christian Gibbons
4. Mai 2020 um 21:26 Uhr
@ChristianGibbons warum funktioniert dann der folgende Code? “char* str = “Hallo Welt”; str = “Auf Wiedersehen Welt”;“`
– Serket
4. Mai 2020 um 21:28 Uhr
@Serket: Das ändert nicht die Zeichenfolge selbst; es ändert den Zeiger
str
(was keine Konstante ist), um auf eine andere Zeichenfolge zu zeigen.char *str = "Hello World"; str[0] = 'J';
wäre undefiniertes Verhalten.– Nate Eldredge
4. Mai 2020 um 21:29 Uhr
@FrançoisAndrieux, das solltest du wahrscheinlich in eine Antwort kopieren.
– Marco Bonelli
4. Mai 2020 um 21:30 Uhr