はい、ローカル変数の有効期間は、それが作成されたscope({
、}
)内にあります。
ローカル変数には、自動ストレージまたはローカルストレージがあります。作成されたスコープが終了すると自動的に破棄されるため、自動。
ただし、ここにあるのは文字列リテラルであり、実装で定義された読み取り専用メモリに割り当てられます。文字列リテラルはローカル変数とは異なり、プログラムの存続期間を通じて存続します。それらは静的な持続時間 [参照1]の寿命を持っています。
注意の言葉!
ただし、文字列リテラルの内容を変更しようとすると、未定義動作(UB)になることに注意してください。ユーザープログラムは、文字列リテラルの内容を変更することはできません。したがって、文字列リテラルを宣言するときにwhile
を使用することを常にお勧めします。const
const char*p = "string";
それ以外の、
char*p = "string";
実際、C ++では、Cではなく文字列リテラルを宣言することは非推奨ですconst
。ただし、で文字列リテラルを宣言すると、でconst
文字列リテラルを変更しようとした場合にコンパイラが通常警告を表示するという利点があります。 2番目のケース。
サンプルプログラム:
#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 Uundefined Behavior
strcpy(str2,source); // Compiler issues a warning
return 0;
}
出力:
cc1:エラーとして扱われる警告
prog.c:関数'main'内:
prog.c:9:エラー:'strcpy'の引数1を渡すと、ポインターターゲットタイプから修飾子が破棄されます
コンパイラが2番目のケースについて警告しますが、最初のケースについては警告しないことに注意してください。
ここで数人のユーザーからの質問に答えるには:
整数リテラルとの関係は何ですか?
つまり、次のコードは有効ですか?
int *foo()
{
return &(2);
}
答えは、このコードは無効ではないということです。これは形式が正しくなく、コンパイラエラーが発生します。
何かのようなもの:
prog.c:3: error: lvalue required as unary ‘&’ operand
文字列リテラルはl値です。つまり、文字列リテラルのアドレスを取得できますが、その内容を変更することはできません。ただし、
他のリテラル(、、、int
など)はr値であり(C標準では、これらの式の値という用語を使用します)、それらのアドレスを取得することはできません。float
char
[参照1] C99標準6.4.5/5「文字列リテラル-セマンティクス」:
変換フェーズ7では、値がゼロのバイトまたはコードが、1つまたは複数の文字列リテラルから生じる各マルチバイト文字シーケンスに追加されます。次に、マルチバイト文字シーケンスを使用して、シーケンスを含めるのに十分な静的ストレージ期間と長さの配列を初期化します。文字列リテラルの場合、配列要素のタイプはcharであり、マルチバイト文字シーケンスの個々のバイトで初期化されます。ワイド文字列リテラルの場合、配列要素の型はwchar_tであり、ワイド文字のシーケンスで初期化されます。
それらの要素が適切な値を持っている場合、これらの配列が別個であるかどうかは指定されていません。プログラムがそのような配列を変更しようとすると、動作は未定義です。