Unterschied zwischen char* und const char*?

Lesezeit: 8 Minuten

Benutzeravatar von Iceman
Eismann

Was ist der Unterschied zwischen

char* name

was auf ein konstantes String-Literal zeigt, und

const char* name

  • 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

Benutzeravatar von ankit.karwasra
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

Benutzeravatar von Alok Save
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 charnicht 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.

Online-Beispielbeispiel:

#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

Benutzeravatar von Afriza N. Arief
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.

Benutzeravatar von Mohit
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 charwohingegen *name oder name[n] wird zu lvalues ​​vom Typ ausgewertet charwelche 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.

Benutzeravatar von Paul Roub
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

1426180cookie-checkUnterschied zwischen char* und const char*?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy