一歩戻ってみましょう... すべてのプログラミング言語 (アセンブリ言語を除く) は、プログラマーにとって考えやすい用語で問題の抽象化を記述していることを理解することが重要です。その抽象的な記述を読み取り、ハードウェアに直接対応する下位レベルの記述を生成するのは、コンパイラの仕事です。
あなたが書くとき:
int x = 6;
整数変数を使用すること、その変数 x を呼び出すこと、および変数の値を 6 にすることをコンパイラーに伝えています。
コンパイラの仕事の 1 つは、その変数を格納する方法を決定することです。C++ 言語では、コンパイラが適切なストレージの種類を決定するのに役立つさまざまな種類の変数スコープが記述されています。
コンパイラは、値を格納するために選択した場所を記憶しているため、値を再度見つけることができます。ローカル変数は、レジスタ名またはスタックの最上位からの相対アドレスになります。グローバルまたは静的の場合、すべてのプログラムのデータの開始に関連するアドレスになります。
メモリ内の実際のアドレスは、プログラムがコンパイルされ、リンクされ、メモリにロードされるまでわかりません (OS が常に同じアドレスにプログラムをロードするとは限らないため)。重要なことは、コンパイラが変数の場所を知っていることです。アクセスするためのコードを生成できます。
2 番目の質問のように、変数の型が何らかのデータ構造である場合、コンパイラはそれをメモリ内のどこに配置するかをまったく同じ方法で選択します。プログラムがその構造体のメンバーにアクセスすると、コンパイラーは構造体のアドレスと構造体内のメンバーのオフセットを知っているため、メンバーのアドレスを計算できます。
したがって、あなたのperson p
例の場合、プログラムp1.type2
がコンパイラを参照するときに、のアドレスを取得しp
てオフセットを追加しますtype2
(おそらく4になります。これは、最初の部分が整数である4であるためにstruct person
取り上げられるためですtype1
バイト (ほとんどの 32 ビット アーキテクチャ))。
との両方を指定する必要p
がtype2
あります。別の人がいる可能性があり (たとえばq
)、操作しようとしている人をコンパイラに通知する必要があるためです。p.type2
は と同じ変数ではなくq.type2
、異なるアドレスになります。