あなたの質問について:
- First Caseで文字列リテラルが読み取り専用で作成されるのはなぜですか?
char *p_var="Sack";
さて、p_var
文字列に割り当てられたメモリの開始アドレスが割り当てられます"Sack"
。C コンストラクトのどこにもキーワードp_var
を配置していないため、 content は読み取り専用ではありません。ただし、 strcpy や strcat などconst
のコンテンツを操作すると、未定義の動作が発生する可能性があります。p_var
引用 C ISO 9899:
この宣言は、プレーンchar 配列オブジェクトを
char s[] = "abc", t[3] = "abc";
定義し、その要素は文字列リテラルで初期化されます。
この宣言は次と同じです:
配列の内容は変更可能です。一方、宣言:はchar へのポインタ型で
定義し、要素が文字列リテラルで初期化された長さ 4の char 型の配列を持つオブジェクトを指すように初期化します。を使用して配列の内容を変更しようとした場合の動作は未定義です。s
t
char s[] = { 'a', 'b', 'c', '\0' },
t[] = { 'a', 'b', 'c' };
char *p = "abc";
p
p
プラットフォームとコンパイラごとに読み取り専用になる理由の説明:
通常、文字列リテラルは「読み取り専用データ」セクションに配置され、プロセス空間に読み取り専用としてマップされます (これが、変更が許可されていないように見える理由です)。
ただし、一部のプラットフォームでは、データ セグメントを書き込み可能にすることができます。
- 文字列リテラルのみを作成でき、float などの他の定数は作成できないのはなぜですか? そして3つ目の質問。
float 定数を作成するには、次を使用する必要があります。
const float f=1.5f;
さて、あなたがやっているとき:
float *p="3.14";
あなたは基本的に文字列リテラルのアドレスをfloatポインタに割り当てています。
でコンパイルしてみてください-Wall -Werror -Wextra
。何が起こっているかがわかります。実際には、 aと a の間に違いがないため、機能し ます。char *
float *
あなたがこれを書いているかのようです:
float *p=(float*) "3.14";
これは、float と char のメモリ アラインメント要件が異なる場合を除き、明確に定義された動作です。異なる場合は、未定義の動作になります (参照: C99、6.3.2.3 p7)。