Ja, die Lebensdauer einer lokalen Variablen liegt innerhalb des Bereichs ( {
, }
), in dem sie erstellt wird.
Lokale Variablen werden automatisch oder lokal gespeichert. Automatisch, weil sie automatisch zerstört werden, sobald der Bereich, in dem sie erstellt wurden, endet.
Was Sie hier haben, ist jedoch ein Zeichenfolgenliteral, das in einem implementierungsdefinierten Nur-Lese-Speicher zugewiesen wird. String-Literale unterscheiden sich von lokalen Variablen und bleiben während der gesamten Programmlebensdauer erhalten. Sie haben eine statische Lebensdauer [Ref 1] .
Ein Wort der Warnung!
Beachten Sie jedoch, dass jeder Versuch, den Inhalt eines Zeichenfolgenliteral zu ändern, ein undefiniertes Verhalten (UB) ist. Benutzerprogramme dürfen den Inhalt eines String-Literal nicht ändern.
Daher wird immer empfohlen, eine const
Weile zu verwenden, um ein Zeichenfolgenliteral zu deklarieren.
const char*p = "string";
anstatt,
char*p = "string";
Tatsächlich ist es in C ++ veraltet, ein Zeichenfolgenliteral ohne das zu deklarieren, const
jedoch nicht in C. Wenn Sie jedoch ein Zeichenfolgenliteral mit a deklarieren, haben const
Sie den Vorteil, dass Compiler normalerweise eine Warnung ausgeben, wenn Sie versuchen, das Zeichenfolgenliteral in zu ändern zweiter Fall.
Beispielprogramm :
#include<string.h>
int main()
{
char *str1 = "string Literal";
const char *str2 = "string Literal";
char source[]="Sample string";
strcpy(str1,source);
strcpy(str2,source);
return 0;
}
Ausgabe:
cc1: Warnungen werden als Fehler behandelt
prog.c: In Funktion 'main':
prog.c: 9: Fehler: Übergabe von Argument 1 von 'strcpy' verwirft Qualifizierer vom Zeigerzieltyp
Beachten Sie, dass der Compiler für den zweiten Fall warnt, nicht jedoch für den ersten.
Um die Frage zu beantworten, die einige Benutzer hier gestellt haben:
Was ist mit integralen Literalen los?
Mit anderen Worten, ist der folgende Code gültig?
int *foo()
{
return &(2);
}
Die Antwort lautet: Nein, dieser Code ist ungültig. Es ist schlecht geformt und gibt einen Compilerfehler aus.
Etwas wie:
prog.c:3: error: lvalue required as unary ‘&’ operand
String-Literale sind l-Werte, dh: Sie können die Adresse eines String-Literals übernehmen, dessen Inhalt jedoch nicht ändern.
Jedoch auch jede andere Literale ( int
, float
, char
, etc.) sind R-Werte (C - Standard verwendet den Begriff der Wert eines Ausdrucks für diese) und deren Adresse gar nicht zu entnehmen.
[Ref 1] C99 Standard 6.4.5 / 5 "String Literals - Semantics":
In der Übersetzungsphase 7 wird an jede Multibyte-Zeichenfolge, die sich aus einem String-Literal oder Literalen ergibt, ein Byte oder ein Code mit dem Wert Null angehängt. Die Multibyte-Zeichenfolge wird dann verwendet, um ein Array mit statischer Speicherdauer und -länge zu initialisieren, das gerade ausreicht, um die Folge aufzunehmen . Bei Zeichenfolgenliteralen haben die Array-Elemente den Typ char und werden mit den einzelnen Bytes der Multibyte-Zeichenfolge initialisiert. Bei Wide-String-Literalen haben die Array-Elemente den Typ wchar_t und werden mit der Folge von Wide-Zeichen initialisiert ...
Es ist nicht spezifiziert, ob diese Arrays unterschiedlich sind, vorausgesetzt, ihre Elemente haben die entsprechenden Werte. Wenn das Programm versucht, ein solches Array zu ändern, ist das Verhalten undefiniert .
int rc
. Seine Lebensdauer endet bei jedem derreturn
-s. Die Zeiger, die Sie zurückgeben, beziehen sich auf Zeichenfolgenliterale. String-Literale haben eine statische Speicherdauer: Ihre Lebensdauer ist mindestens so lang wie die des Programms.