次のように宣言すると、舞台裏で何が起こるか:-
char a[]="June 14";
と
char *a="June 14";
上記の 2 つの宣言 ( stack 、データ セグメントなど) にメモリがどのように割り当てられるかを意味します。
以下は、典型的な C 実装用です。
char a[] = "June 14";
最初に「June 14」を含む配列を定義します (終端の null を含む)。これらの文字は、プログラムの実行開始時にメモリにロードされる実行可能ファイルのデータ セクションに配置されます。(注: ロードは、実際にはプログラムの仮想アドレス空間の一部であるという意味で、物理的にすぐにメモリに読み込まれないという意味で、仮想的である可能性があります。)
char *a = "June 14";
は 2 つのことを定義します。1 つ目は「June 14」を含む文字列です。これらの文字は、実行可能ファイルのデータ セクションに配置されます。読み取り専用 (定数とも呼ばれる) データ セクションの場合があります。2 つ目はポインターです。ポインターは、データ セクション (読み取り専用ではない) にも配置される可能性があります。ポインタは文字列のアドレスで初期化されます。(プログラムがターゲット システムでどのようにリンクされているかによって、実行可能ファイルには、実際のアドレス自体ではなく、ロード時にアドレスを入力する方法に関するシステムへの指示が含まれる場合があります。)
char a[] = "June 14";
最初に「June 14」を含む配列を定義します。ただし、この配列は、実行が宣言に到達するたびに作成および初期化する必要があります。(ファイル スコープの宣言では、プログラムの開始時に配列を初期化するだけで済みます。) この初期化を完了するために、コンパイラは実行可能ファイルのデータ セクション (おそらく読み取り専用のデータ セクション) に「June 14」を配置します。 )。実行が宣言に到達する (または到達しようとしている) ときはいつでも、コンパイラーはスタック上にいくらかのスペースを割り当て、読み取り専用コピーからスタック上の新しいスペースに文字をコピーします。
char *a = "June 14";
文字列がデータ セクション (おそらく読み取り専用) に配置され、ポインターが作成されるという点で、ファイル スコープ宣言に似ています。ただし、ポインターは通常、データ セクションではなくスタック上にあります。(私が「名目上」と言ったのは、最適化の結果、実際にはスタック上ではなくプロセッサ レジスタ内にあるようなポインタになる可能性が非常に高いためです。または、完全に最適化されていないことさえあります)。他の情報からの文字列のアドレス。(たとえば、ローダーはデータ セクションの開始をロードしたアドレスにレジスタを設定する場合があるため、ポインターの初期値の計算ではそのアドレスが使用され、データ セクション内の文字列のオフセットがそれに追加されます。 )