8

次のような変数を宣言すると、次のようになります。

 int x = 6;

正確には何xですか?メモリ内のアドレスは通常 16 進数です。
また、X を呼び出しているとき

x = 2;

コンパイラはどこにあるかをどのように知っていxますか? x住所ではありません。

それが私の最初の質問でした。

2番目:
オブジェクトがあるとしましょう:
Person p;
p2つのデータメンバーがあります:

 int type1, int type2;

とは正確には何ですか?pなぜ に移動してからp変数に移動する必要があるのですか?

p.type1, p->type1.
4

11 に答える 11

5

の場合int x = 6xは、コードを記述し、コンパイラがそれをコンパイルするのに役立つ単なる名前です。これは基本的にメモリ内のある場所のエイリアスであるため、後で簡単にアクセスできるようになります。これにより、同じ場所x = 2に値を書き込む必要があることが、ユーザーとコンパイラの両方に伝えられます。2

前と同じですが、より多くのスペースを占有sizeof(Person)します (正確には)。がa へのポインタである場合 (または演算子をオーバーロードした場合、ただしそうではない場合) にp->type1のみ有効です。オブジェクトのどの部分にアクセスするかを指定するために使用される構文です。pPerson->p.type1

于 2012-10-12T14:10:42.407 に答える
5
int x=6 ;

ここxに識別子、つまりname given to memory area値6が格納されている場所があります。
x値 6 が格納されているメモリ領域を識別するための単純な名前です。
u が変数を宣言すると、その時点でコンパイラは変数名を識別子テーブルに格納します。

の場合person p、ここでもpメモリ領域に付けられた名前です。これには、2 つのデータ メンバtype1とデータが格納されます。type2

type1&の値にアクセスするにはtype2、まずそれらが保存されているメモリ領域を見つける必要があります。そのため、最初にメモリ領域にアクセスする必要があり、p次にアクセスできますtype1 * type2

于 2012-10-12T14:08:14.647 に答える
4

x「ロケーター値」を意味する左辺値です。xコンパイラがどこにあるかを知っているため、そのように呼び出されます。つまりx、ある意味ではアドレス、またはアドレスを推測できるものです。

あれは読んだ時だけ値になる

int a = x;

その場合、コンパイラは を取りx、その場所の値を読み取り、それ以降、その初期化でxはその値を表します。残念ながら、この「値の読み取り」は暗黙のプロセスであるため、テキストxが値であるか左辺値であるかは、表示される場所によって異なります。

于 2012-10-12T14:12:14.520 に答える
3
int x = 6;

Xとは正確には何ですか?

xは、メモリ内の場所に付けられた名前として定義できる変数です。

コンパイラはxがどこにあるかをどのように知るのですか?

コンパイラが変数名を実際のメモリ位置にマップするために内部的に使用するシンボルテーブルと呼ばれるものがあります。

于 2012-10-12T14:21:23.003 に答える
1

それが変数であるということは、自信を持って言えることのすべてです。

オプティマイザがメモリアドレスをレジスタに配置した場合、メモリアドレスがない可能性があります。メモリアドレスがある場合は、固定の絶対アドレス(再配置不可能なコードのグローバルおよび静的の場合)、他のオブジェクトに関連するアドレス(非静的メンバーの場合)、またはスタックに関連するアドレスを指定できます。フレーム(自動ローカル変数用)。

コンパイラーが常に値を予測し、使用するたびにその値を置き換えることができるとコンパイラーが判断した場合、それは保管場所でさえない可能性があります。

&変数でaddress-of演算子を使用する場合、コンパイラーは変数にメモリー位置を指定する必要があります。

于 2012-10-12T14:33:08.877 に答える
1

x変数です。より正確には、変数が参照する情報 (データ) が格納されている場所の名前またはラベルです。異なる変数を区別するためにラベルが必要です。あなた(プログラマー)があなたを助けるためにそこにいます。

pも可変ですが、タイプはPersonです。そしてPersonデータ構造です - それはあなたが構造を通してアクセスするデータを保持します。Andpは、このタイプのオブジェクト (ei は構造体のインスタンス化) です。同じタイプのオブジェクトを 2 つ持つことができます

Person p;
Person someone;

アクセスしたいデータ/メンバーを知るために、使用しますp.data someone.data

なぜp->dataですか?

p->data構文は次と同等です(*p).data

それはポインタとは何かを説明することになります。先ほど言ったように、変数は情報 (データ) を格納する場所です。簡単に言えば、ポインターはメモリアドレスを格納する変数です。つまり、メモリのどこかに保存されている別の値を指します

例えば:

Person p; // variable of type Person 
Person *pointer_to_p = &p; 
// a pointer that points to the variable p 
// it holds the address of p - that's what &p does it returns the address of a varible

*pin(*p).dataは、ポインターの逆参照 (ポインターが指す値へのアクセス) と呼ばれます。

詳細については、ポインターをグーグルで検索するか、本を読んでもらうことをお勧めします

于 2012-10-12T14:18:22.313 に答える
1

言葉は物ではありません。

、 、 、および はすべてx名前または識別子です。だから、あなたは本当に彼らが何を特定するのかを尋ねていると思います. 答えは、言語仕様によって作成された特定の要件を満たしているのように動作する何かを識別しているということです。この特定されたものが実際に何であるかは、プラットフォーム、コンパイラ、おそらくどの最適化をオンにしたかなどによって異なります。pp.type1

それでは、ステートメントを見てみましょう

int x = 6;

あなたはそれxが今(このスコープとおそらくネストされたスコープで)int(それが何であれ)を参照し、それに初期整数リテラル value を与えると言っています6

それで、何intですか?範囲内で単一の (正または負の) 整数値を保持できるものです[std::numeric_limits<int>::min(),std::numeric_limits<int>::max()]。その正確なサイズはアーキテクチャに依存しますが、少なくとも a と同じ大きさで、a (IIRC)charよりも大きくありません。long

これが何であるかの可能性のある候補:

  • intグローバル宣言の場合は、リンカー シンボル (実行時に再配置される可能性があります) に関連付けられた、プラットフォーム上のものを保持するのに十分なメモリ。したがって、参照するすべてのコードxは同じメモリ位置を使用します。
  • 関数スコープのローカル変数の場合、スタック (またはスタック フレーム) ポインター レジスターからの固定オフセットに十分なメモリ: コンパイラーは、各関数内にここに配置する変数を追跡し、どのオフセットが関連付けられているかを記憶する責任があります。各識別子。これは一般的なデフォルト (最適化されていない) ケースです。
  • を格納するのに十分なサイズのレジスタint: : アドレスを取得しない場合はx、レジスタ内で一生を過ごすことができる場合がありますが、アドレスを取得するか、コンパイラがすべての変数のレジスタを使い果たした場合 (または関数呼び出し全体でそれらを保存する必要があります)、x作業中にレジスタにロードされ、スタックにスピルバックされる可能性があります。繰り返しますが、現在いつ xがレジスターであるか (およびどのレジスターであるか)、いつメモリ位置であるかを覚えておくのはコンパイラ次第です。

ご覧のとおりx、プログラムの実行中のさまざまな時点で、識別される「もの」は実際には多くのものになる可能性があります。

何かを最適化したり、メモリを慎重にレイアウトしたりしていない限り、より有用な質問はx のプロパティは何ですか?

標準 (または実際には任意の言語仕様) のポイントは、型、変数、および動作に関するいくつかの有用な保証を作成し、コンパイラにそれらの保証を達成する方法を選択させることです。

于 2012-10-12T16:02:49.673 に答える
1

x変数識別子です。変数は、サイズがあり、null にできないという点でアドレスとは異なります。のアドレスはxで取得できます&x。次のコードを検討してください。

int x = 5;
int* p = &x; // the pointer p now refers to x
x = 6;

の値を変更しただけですが、 (ポインターの「逆参照」と呼ばれる) のx値を取得すると、 6 も取得されます。タイプが持つ「int」。*ppx

于 2012-10-12T14:12:03.827 に答える
1

一歩戻ってみましょう... すべてのプログラミング言語 (アセンブリ言語を除く) は、プログラマーにとって考えやすい用語で問題の抽象化を記述していることを理解することが重要です。その抽象的な記述を読み取り、ハードウェアに直接対応する下位レベルの記述を生成するのは、コンパイラの仕事です。

あなたが書くとき:

int x = 6;

整数変数を使用すること、その変数 x を呼び出すこと、および変数の値を 6 にすることをコンパイラーに伝えています。

コンパイラの仕事の 1 つは、その変数を格納する方法を決定することです。C++ 言語では、コンパイラが適切なストレージの種類を決定するのに役立つさまざまな種類の変数スコープが記述されています。

  • ローカル変数 (関数内で宣言された) は通常、スタック上のメモリに格納されますが、小さな値 (整数など) はレジスタに保持される可能性があります。

  • グローバル変数または静的変数がメモリに格納されます。

コンパイラは、値を格納するために選択した場所を記憶しているため、値を再度見つけることができます。ローカル変数は、レジスタ名またはスタックの最上位からの相対アドレスになります。グローバルまたは静的の場合、すべてのプログラムのデータの開始に関連するアドレスになります。

メモリ内の実際のアドレスは、プログラムがコンパイルされ、リンクされ、メモリにロードされるまでわかりません (OS が常に同じアドレスにプログラムをロードするとは限らないため)。重要なことは、コンパイラが変数の場所を知っていることです。アクセスするためのコードを生成できます。

2 番目の質問のように、変数の型が何らかのデータ構造である場合、コンパイラはそれをメモリ内のどこに配置するかをまったく同じ方法で選択します。プログラムがその構造体のメンバーにアクセスすると、コンパイラーは構造体のアドレスと構造体内のメンバーのオフセットを知っているため、メンバーのアドレスを計算できます。

したがって、あなたのperson p例の場合、プログラムp1.type2がコンパイラを参照するときに、のアドレスを取得しpてオフセットを追加しますtype2(おそらく4になります。これは、最初の部分が整数である4であるためにstruct person取り上げられるためですtype1バイト (ほとんどの 32 ビット アーキテクチャ))。

との両方を指定する必要ptype2あります。別の人がいる可能性があり (たとえばq)、操作しようとしている人をコンパイラに通知する必要があるためです。p.type2は と同じ変数ではなくq.type2、異なるアドレスになります。

于 2012-10-12T16:17:34.800 に答える
0

スタックとヒープについて読んでください。

x は一意のアドレスでスタックにプッシュされます。ただし、x を呼び出すだけです。

しかし試してみてください cout << &x;

それが本当の住所です

于 2012-10-12T14:11:18.293 に答える
-1

変数を宣言すると、コンパイラはそれを変数属性テーブルにマップします。そして、そのテーブルにはアドレスとサイズ、タイプなどが含まれているため、コンパイラは必要に応じてこのテーブルから情報を取得します。

于 2012-10-12T14:14:51.303 に答える