Was ist der Unterschied zwischen
char* name
was auf ein konstantes String-Literal zeigt, und
const char* name
Eismann
Was ist der Unterschied zwischen
char* name
was auf ein konstantes String-Literal zeigt, und
const char* name
ankit.karwasra
char*
ist ein veränderlich Zeiger auf a veränderlich Zeichenkette.
const char*
ist ein veränderlich Zeiger auf ein unveränderlich Zeichenkette. Sie können den Inhalt der Position(en), auf die dieser Zeiger zeigt, nicht ändern. Außerdem müssen Compiler Fehlermeldungen ausgeben, wenn Sie dies versuchen. Aus dem gleichen Grund ist die Konvertierung von const char *
zu char*
ist veraltet.
char* const
ist ein unveränderlich Zeiger (er kann nicht auf einen anderen Ort zeigen) aber der Inhalt des Ortes, auf den es zeigt veränderlich.
const char* const
ist ein unveränderlich Zeiger auf ein unveränderlich Zeichenkette.
Verwirrung kann durch die Verwendung einer Variablen nach den oben genannten Aussagen und durch Verweis auf diese Variable ausgeräumt werden.
– ankit.karwasra
8. Oktober 2013 um 9:16 Uhr
@ankit.karwasra, du hast noch einen verpasst: char const *
– Schrittmacher
13. Mai 2015 um 3:27 Uhr
Wird nicht mutieren char *
gib Segmentierungsfehler beim Laufen?
– Divyanshu Maithani
21. Februar 2017 um 8:52 Uhr
Also verwende ich const
wenn ich möchte, dass der Compiler einen Fehler ausgibt, wenn ich die Daten versehentlich vergessen und geändert habe, richtig?
– Buchhalter م
6. April 2019 um 22:12 Uhr
@DivyanshuMaithani Es kommt darauf an wo char *
geschaffen. Zum Beispiel: char *s = "A string"
setzt "A string"
in den Codeabschnitt (RO-Speicher) Ihrer Binärdatei. Fehler beim Schreiben in dieses Speichersegment. Aber char *s = malloc(sizeof(char) * 10)
weist Speicher auf dem Heap zu, und dieser Speicherabschnitt ist beschreibbar und weist daher beim Schreiben keinen Fehler auf.
– d4rwel
21. April 2020 um 12:39 Uhr
Alok Speichern
char *name
Sie können das Zeichen in das ändern name
Punkte und auch das Zeichen, auf das es zeigt.
const char* name
Sie können das Zeichen in das ändern name
zeigt, aber Sie können das Zeichen, auf das es zeigt, nicht ändern.
Korrektur: Sie können den Zeiger ändern, aber nicht das Zeichen zu dem name
verweist auf (https://msdn.microsoft.com/en-us/library/vstudio/whkd4k6a(v=vs.100).aspx, siehe “Beispiele”). In diesem Fall ist die const
Bezeichner gilt für char
nicht das Sternchen.
Laut der MSDN-Seite und http://en.cppreference.com/w/cpp/language/declarationsdas const
Vor dem *
ist Teil der decl-specifier-Sequenz, während die const
nach *
ist Teil des Deklarators.
Aus diesem Grund können auf eine Deklarationsspezifizierersequenz mehrere Deklaratoren folgen const char * c1, c2
erklärt c1
wie const char *
und c2
wie const char
.
BEARBEITEN:
Aus den Kommentaren scheint Ihre Frage nach dem Unterschied zwischen den beiden Deklarationen zu fragen, wenn der Zeiger auf ein Zeichenfolgenliteral zeigt.
In diesem Fall Sie sollte nicht Ändern Sie das Zeichen zu dem name
Punkte, wie es dazu kommen könnte Undefiniertes Verhalten. Zeichenfolgenliterale können in Nur-Lese-Speicherbereichen (implementiert definiert) zugewiesen werden, und ein Benutzerprogramm sollte sie ohnehin nicht ändern. Jeder Versuch, dies zu tun, führt zu undefiniertem Verhalten.
Der einzige Unterschied in diesem Fall (zur Verwendung mit Zeichenfolgenliteralen) besteht also darin, dass die zweite Deklaration Ihnen einen leichten Vorteil verschafft. Compiler geben Ihnen normalerweise eine Warnung aus, falls Sie versuchen, das Zeichenfolgenliteral im zweiten Fall zu ändern.
#include <string.h>
int main()
{
char *str1 = "string Literal";
const char *str2 = "string Literal";
char source[] = "Sample string";
strcpy(str1,source); //No warning or error, just Undefined Behavior
strcpy(str2,source); //Compiler issues a warning
return 0;
}
Ausgabe:
cc1: Warnungen werden als Fehler behandelt
prog.c: In Funktion ‘main’:
prog.c:9: Fehler: Beim Übergeben von Argument 1 von „strcpy“ werden Qualifizierer vom Zeigerzieltyp verworfen
Beachten Sie, dass der Compiler im zweiten Fall warnt, aber nicht im ersten.
Danke. Ich habe mit dem konstanten String-Literal gemischt, das wie folgt definiert ist: char* name = “String Literal”; Das Ändern von “String Literal” ist undefiniert.
– Eismann
23. März 2012 um 4:20 Uhr
@ user1279782: Ähm, warte! Sprechen Sie hier von Pointes, die auf String-Literale zeigen? In diesem Fall Sie sollte nicht Ändern Sie das Zeichen, zu dem die name
Punkte in beiden Fällen. Es könnte zu UB führen.
– Alok Speichern
23. März 2012 um 4:24 Uhr
Ja, das war der Punkt. In diesem Fall verhalten sich also char* name und const char* name ähnlich, richtig?
– Eismann
23. März 2012 um 4:28 Uhr
Diese Antwort ist entweder äußerst mehrdeutig oder schlichtweg falsch. Ich würde interpretieren “Sie können das Zeichen, auf das der Name zeigt, nicht ändern, aber Sie können das Zeichen ändern, auf das es zeigt.” Da der Zeiger selbst nicht geändert werden kann, aber der Speicherort geändert werden kann, auf den er zeigt, ist dies falsch: ideone.com/6lUY9s alternativ für reines C: ideone.com/x3PcTP
– verhüllte Nacht
4. Januar 2013 um 23:34 Uhr
@shroudednight: Sie müssen etwas mehr über undefinierte Verhaltensweisen lernen und unterscheiden zwischen: erlaubt und sollte nicht gemacht werden. 🙂
– Alok Speichern
5. Januar 2013 um 5:29 Uhr
Afriza N. Arief
char mystring[101] = "My sample string";
const char * constcharp = mystring; // (1)
char const * charconstp = mystring; // (2) the same as (1)
char * const charpconst = mystring; // (3)
constcharp++; // ok
charconstp++; // ok
charpconst++; // compile error
constcharp[3] = '\0'; // compile error
charconstp[3] = '\0'; // compile error
charpconst[3] = '\0'; // ok
// String literals
char * lcharp = "My string literal";
const char * lconstcharp = "My string literal";
lcharp[0] = 'X'; // Segmentation fault (crash) during run-time
lconstcharp[0] = 'X'; // compile error
// *not* a string literal
const char astr[101] = "My mutable string";
astr[0] = 'X'; // compile error
((char*)astr)[0] = 'X'; // ok
Keiner Ihrer Zeiger zeigt gemäß der Frage auf “konstante Zeichenfolgenliterale”.
– Café
23. März 2012 um 4:25 Uhr
Es ist erwähnenswert, dass das Ändern der char *
Wert gibt Segmentierungsfehler, da wir versuchen, ein Zeichenfolgenliteral zu ändern (das im Nur-Lese-Speicher vorhanden ist)
– Divyanshu Maithani
21. Februar 2017 um 8:50 Uhr
Können Sie die letzte Zeile erklären, die ich nicht verstehen konnte?
– lorem1213
16. Juli um 20:09 Uhr
In keinem Fall können Sie ein Zeichenfolgenliteral ändern, unabhängig davon, ob der Zeiger auf dieses Zeichenfolgenliteral als deklariert ist char *
oder const char *
.
Der Unterschied besteht jedoch darin, dass, wenn der Zeiger ist const char *
dann muss der Compiler eine Diagnose ausgeben, wenn Sie versuchen, den Wert, auf den gezeigt wird, zu ändern, aber wenn der Zeiger es ist char *
dann geht es nicht.
Mohit
FALL 1:
char *str = "Hello";
str[0] = 'M' //Warning may be issued by compiler, and will cause segmentation fault upon running the programme
Das obige setzt str so, dass es auf den Literalwert „Hello“ zeigt, der im Binärbild des Programms fest codiert ist, das im Speicher als schreibgeschützt gekennzeichnet ist, was bedeutet, dass jede Änderung in diesem String-Literal illegal ist und Segmentierungsfehler auslösen würde.
FALL 2:
const char *str = "Hello";
str[0] = 'M' //Compile time error
FALL 3:
char str[] = "Hello";
str[0] = 'M'; // legal and change the str = "Mello".
Die Frage ist, was ist der Unterschied zwischen
char *name
was auf ein konstantes String-Literal zeigt, und
const char *cname
Dh gegeben
char *name = "foo";
und
const char *cname = "foo";
Es gibt keinen großen Unterschied zwischen den 2 und beide können als richtig angesehen werden. Aufgrund des langen Vermächtnisses von C-Code haben die Zeichenfolgenliterale einen Typ von char[]
nicht const char[]
und es gibt viele ältere Codes, die ebenfalls akzeptieren char *
Anstatt von const char *
auch wenn sie die Argumente nicht ändern.
Der Hauptunterschied der 2 im Allgemeinen ist das *cname
oder cname[n]
wird zu lvalues vom Typ ausgewertet const char
wohingegen *name
oder name[n]
wird zu lvalues vom Typ ausgewertet char
welche sind änderbare lvalues. Ein konformer Compiler ist erforderlich, um eine Diagnosemeldung zu erzeugen, wenn Ziel der Zuweisung ist kein änderbarer lvalue; es muss keine Warnung bei der Zuweisung an lvalues vom Typ erzeugen char
:
name[0] = 'x'; // no diagnostics *needed*
cname[0] = 'x'; // a conforming compiler *must* produce a diagnostic message
Der Compiler ist es nicht erforderlich um die Kompilierung in jedem Fall zu stoppen; es genügt, dass es a erzeugt Warnung für den Auftrag an cname[0]
. Das resultierende Programm ist nicht a Korrekt Programm. Das Verhalten des Konstrukts ist nicht definiert. Es kann abstürzen oder noch schlimmer, es kann nicht abstürzen und das Zeichenfolgenliteral im Speicher ändern.
Paul Roub
Das erste kannst du tatsächlich ändern, wenn du willst, das zweite nicht. Informieren Sie sich über const
Korrektheit (es gibt einige nette Anleitungen über den Unterschied). Es gibt auch char const * name
wo man es nicht umpolen kann.
Was genau kann sich ändern?
– Antti Haapala – Слава Україні
24. August 2017 um 18:49 Uhr
Was meinst du mit “Konstante String-Literal” in C (nicht C++)
– gbulmer
23. März 2012 um 4:49 Uhr
… char *name kann dazu gebracht werden, auf ein konstantes String-Literal zu zeigen
– Eismann
23. März 2012 um 15:15 Uhr
Die Konstante in “konstantes Zeichenfolgenliteral” ist redundant, da alle Zeichenfolgenliterale theoretisch konstante Entitäten sind. Es ist der Inhalt der Variablen, der entweder konstant oder veränderlich gemacht werden kann. Die “const”-Deklaration löst einfach einen Kompilierungsfehler aus, wenn Sie versuchen, den Inhalt des Zeichens zu ändern, auf das “name” zeigt.
– Cupcake
31. Juli 2016 um 4:49 Uhr
Ganz einfach: “char *name” name ist ein Zeiger auf char, dh beide können hier geändert werden. “const char *name” name ist ein Zeiger auf const char, dh der Zeiger kann sich ändern, aber nicht char.
– akD
27. April 2017 um 6:20 Uhr
Lesen Sie diese Dinge von rechts nach links.
– JP Zhang
24. Mai 2020 um 16:14 Uhr