wenn ich dies tue: char * Text; text = "Hallo"; es funktioniert, aber was ich hier wirklich mache ist die Initialisierung eines Zeigers von char und es kann nicht den Wert "Hallo", nur der Wert einer Adresse halten? Wenn ich das Gleiche mit Int mache, funktioniert es nicht warum?C++ Zeiger der Char Ausnahme
Antwort
Eine literale Zeichenfolge endet als Zeiger auf Ihren Datenabschnitt Ihres Programms, so dass es sicher ist. Aber wenn man einen int zu einem int*
zuweisen wird es erzählt die OS, dass Speicherplatz zu verwenden, die nicht sicher ist
Nach dem C++ Standard § 2.14.5/8
8 Ordinary Stringliterale und UTF -8 Zeichenfolgenliterale werden auch als Zeichenfolgenliterale bezeichnet. Ein schmaler Stringliteral hat „Array von n const char“ geben, wobei n die Größe der Zeichenfolge wie unten definiert ist, und hat statische Speicherdauer
und Abschnitt 2.14.5/14
14 Nach jeder notwendigen Verkettung wird in der Übersetzungsphase 7 (2.2) '\ 0' an jedes String-Literal angehängt, so dass Programme, die einen String scannen, sein Ende finden können.
"Hello"
ist ein schmaler Stringliteral, es produziert
static const char __hello_str[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
In C++, von C geerbt hat, ist das Konzept der array-pointer equivalence, die in diesem Zusammenhang auf die Tatsache, läuft darauf hinaus, dass ein Array - oder String-Literal - wird gerne in einen Zeiger zerfallen.
char* text;
text = "hello";
führt ein statisches, NUL-terminierte Zeichenfeld in dem Datenabschnitt des Programms, und ordnet diese Adresse an dem char * pointer Variable ist.
Technisch verletzen wir hier die const
ness des Arrays, aber viele Compiler erlauben dies aufgrund des alten C-Codes. Die C++ Standard Zustände in Anhang C jedoch:
Ziffer 2.14.5: to Der Typ eines Stringliteral ist aus „array of char“ verändert den Typ eines char16_t „array of const char“. Das Zeichenfolgenliteral wird von "Array eines Integer-Typs" in "Array von Const char16_t" geändert. Der Typ eines Zeichenfolgenliterals char32_t wird von "Array eines Integer-Typs" in "Array von Const Char32_t" geändert. Der Typ eines Wide-String-Literals wird von "array of wchar_t" in "array of const wchar_t" geändert. Begründung: Dadurch wird vermieden, dass eine unangemessene überladene Funktion aufgerufen wird, die möglicherweise ihr Argument ändern kann.
Die alten Konvertierungen wurden vor einiger Zeit eingestellt und sind seit C++ 11 illegal.Der richtige Weg, dies zu tun ist:
const char* text;
text = "hello"; // correct
Es ist unklar, ob Sie
int* text;
text = "hello"; // error: incompatible types int* vs const char*
zu schreiben versuchen, oder ob Sie versuchen, so etwas wie zu tun:
const int a = 1;
int* ptr;
ptr = &a; // error: int* vs const int*.
Re „Die Legacy-Konvertierungen sind veraltet und wird in zukünftigen Version von C++ wird vermutlich illegal werden. ", seit C++ 11 ist die Umwandlung eines schmalen String-Literals in" char * "ungültig. –
@ Cheersandthth.-Alf Danke, aktualisiert. – kfsone
Re Beispiel
char* text; text = "Hello"; //! Not OK
Die Zeichenfolgenliteral hat den Typ char const [6]
, wobei der Wert ein abschließendes Nullbyte ist.
Die Konvertierung in char*
ist ungültig ab C++ 11 und später.
In C++ 98 und C++ 03 war es jedoch für Abwärtskompatibilität mit C gültig. Es gab eine spezielle Regel für String-Literale, die das Löschen der const
erlaubte. In C++ 11 und später müssen Sie die const
-ness halten (was sicherer ist die wörtliche weil Modifizierung nicht definiertes Verhalten ist), dh
char const* text; text = "Hello";
Hier die Stringliteral Zerfälle auf einen char const*
Zeiger, der auf die Punkte erster char
Wert, und dieser Zeigerwert wird text
zugewiesen.
Es gibt keine solche implizite Konvertierung von int
zum Zeigerwert. Aber wenn Sie ein Array von int
hätten, würde dieses Array implizit in Zeiger konvertieren. ZB
int const a[] = { 2, 7, 1, 8, 2, 8, 1, 8, 2, 8};
int const* p = a;
Dies sollte helfen: http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – user2079303