はい、ローカル変数の有効期間は、それが作成されたスコープ({
、}
)内にあります。
ローカル変数には、自動ストレージまたはローカルストレージがあります。自動それらは自動的にそれらが端を作成されている範囲内で、スコープ一度破壊されているため。
ただし、ここにあるのは文字列リテラルであり、実装で定義された読み取り専用メモリに割り当てられます。文字列リテラルはローカル変数とは異なり、プログラムの存続期間を通じて存続します。それらは静的な持続時間 [参照1]の寿命を持っています。
注意の言葉!
ただし、文字列リテラルの内容を変更しようとすると、未定義の動作(UB)になることに注意してください。ユーザープログラムは、文字列リテラルの内容を変更することはできません。
したがって、const
文字列リテラルを宣言するときは常にwhileを使用することをお勧めします。
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);
strcpy(str2,source);
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
、float
、char
、など)はR値である(C標準は、用語を使用する式の値これらのために)およびそれらのアドレスは全く取ることができません。
[参照1] C99標準6.4.5 / 5「文字列リテラル-セマンティクス」:
変換フェーズ7では、値がゼロのバイトまたはコードが、1つまたは複数の文字列リテラルから生じる各マルチバイト文字シーケンスに追加されます。次に、マルチバイト文字シーケンスを使用して、シーケンスを含めるのに十分な静的ストレージ期間と長さの配列を初期化します。文字列リテラルの場合、配列要素の型はcharであり、マルチバイト文字シーケンスの個々のバイトで初期化されます。ワイド文字列リテラルの場合、配列要素の型はwchar_tであり、ワイド文字のシーケンスで初期化されます。
それらの要素が適切な値を持っている場合、これらの配列が異なるかどうかは指定されていません。プログラムがそのような配列を変更しようとした場合、動作は未定義です。
int rc
です。その存続期間は、return
-sのそれぞれで終了します。返すポインタは文字列リテラルです。文字列リテラルには静的な保存期間があります。その有効期間は、少なくともプログラムの有効期間と同じです。