変数とメモリ位置の違いは何ですか?[閉まっている]


38

最近、フラッシュカードのように、ポインタを視覚的に説明しようとしています。

質問001:これは、コンピューターのメモリ内の場所の描画です。その住所は本当0x23452ですか?どうして?

ここに画像の説明を入力してください

回答:はい、0x23452コンピューターがこの場所を見つけることができる場所について説明しているためです。


質問002:文字bがメモリの場所に保存されているのは本当0x23452ですか?どうして?

ここに画像の説明を入力してください

回答:いいえa。キャラクターは実際にその中に保存されているためです。


質問003:ポインターがメモリの場所に保存されているのは本当0x23452ですか?どうして?

ここに画像の説明を入力してください

回答:はい、メモリロケーションのアドレスは0x34501内部に保存されているためです。


質問004:ポインターがメモリの場所に保存されているのは本当0x23452ですか?どうして?

ここに画像の説明を入力してください

回答:はい、別のメモリ位置のアドレスが内部に保存されているためです。


今、私が心配している部分について。ソフトウェアエンジニアは、次のように私へのポインタを説明しました。

ポインタは、値が別の変数のメモリアドレスである変数です。

すべてを紹介した4つのフラッシュカードに基づいて、少し異なる方法でポインターを定義します。

ポインタは、値が別のメモリ位置のメモリアドレスであるメモリ位置です。

変数はメモリの場所と同じだと言っても安全ですか?

そうでない場合は、誰が正しいですか?変数とメモリ位置の違いは何ですか?


37
そここれらの写真を読んで誰もがボックスの下進数は、メモリ・アドレスであることを、あなたの意図を知っているだろうことをここ暗黙の前提だ、そのa0x23453nil等それらの中のものは値です。それはあなたには自明のように思えるかもしれませんが、これらのフィールドがどのように定義されているかを見ずに、これらの質問に決定的な答えを出すのは気に入らないでしょう。a2番目の画像が文字、文字列(異なる場合)、または変数の名前であるかどうかを実際に知る方法はありません。文字列の場合、文字列でnilもありますか?または「null」値?
ilkkachu

39
質問1は悪い質問です。それは、読者が他の質問に答える前に読者に伝える必要があるものです。質問ではなく、読者に提供される情報である必要があります。「次の質問では、ボックスはメモリの場所であり、下の16進数はアドレスです」。
17日26

15
質問3は、コンテキストを考えると答えることができません。メモリに保存されている値がアプリケーションレベルでどのように解釈/使用されているかをバイトレベルで伝える方法はありません。
17日26

6
ここで書いていることはすべて、CまたはC ++には当てはまりますが、基本的に明示的なポインター参照/逆参照を持たない言語には当てはまりません。変数が値を入れるスロットであるというメタファー全体が、代入によってコピーせずに変数がオブジェクトを指すようになる言語(Python、Java、C#、Ruby、JavaScript、その他多く)の内訳、およびオブジェクトへの突然変異は、それを指すすべての変数を通して可視です。Pythonのドキュメントでは、この理由でオブジェクトに掛かっている名前タグとして変数の代替メタファーを使用しています。
マークアメリー

19
ところで、これを既に理解しているなら許してください、しかしこれは混乱のポイントであるように見えます-この "0x23452"表記は16進形式で数字を示すための単なる方法であり、それは単に便宜上行われています。しかし、これは単なる数字です。0xプレフィックスは、それがポインターであることを示すものではありません。メモリに保存されるのは、文字通り意味のない数字です(メモリ位置にプレーンな10進整数をラベル付けできます)。意味(つまり、数値の解釈方法)は言語に由来します-変数のタイプと使用方法。
フィリップミロヴァーノビッチ

回答:


69

変数は、アルゴリズムの意図に沿った論理構造であり、メモリ位置はコンピューターの動作を記述する物理構造です。一般的に、プログラムを実行するために、変数の論理的概念とコンピューターのストレージとの間に(コンパイラー生成)マッピングがあります。

(アセンブリ言語でも、(論理)変数がアルゴリズムとインテントになり、(物理)メモリ位置の概念がありますが、アセンブリではより混同されます。)

変数は高レベルの概念です。変数は、不明(数学、プログラミングの割り当てなど)か、値で置き換えることができるプレースホルダー(プログラミングの場合:パラメーター)のいずれかを表します。

メモリロケーションは、低レベルの概念です。メモリの場所は、変数の値を格納するために値を格納するために使用できます。ただし、CPUレジスタは、いくつかの変数の値を保存する別の方法です。CPUレジスタも低レベルのストレージ場所ですが、アドレスがなく、名前だけがあるため、メモリの場所ではありません。

ある意味では、変数はプログラムの意図を表現するための抽象化のメカニズムであり、メモリの場所はストレージと検索を提供する処理環境の物理的なエンティティです。

質問003:ポインターがメモリ位置0x23452内に保存されているのは本当ですか?どうして?

はっきりと言うことはできません。アドレスとして機能する値がそこにあるからといって、それがそのアドレスであることを意味するのではなく、代わりに整数(10進数)‭144466‬である可能性があります。私たちは、単に数値がどのように現れるかに基づいて、値の解釈を仮定することはできません。

質問004:ポインターがメモリ位置0x23452内に保存されているのは本当ですか?どうして?

これは確かに奇妙な質問です。彼らはボックスに基づいていくつかの仮定を期待していますが、アドレスが各ボックスごとに1ずつ増加することに注意しましょう。現代のコンピュータでは、それは各ボックスがバイトを保持できることを意味します。バイトのアドレス指定は、数十年前から標準でした。ただし、バイトは8ビットのみで、0〜255の範囲で指定できます(符号なしの値の場合)。しかし、これらのアドレスの1つに格納されている値ははるかに大きいため、非常に疑わしいです。(これがワードアドレスマシンである場合、これは機能しますが、それは言わず、一部の教育用マシンはそうですが、今日はほとんどありません。)

すべてを紹介した4つのフラッシュカードに基づいて、少し異なる方法でポインターを定義します。

ポインタは、値が別のメモリ位置のメモリアドレスであるメモリ位置です。

この考え方が正しい状況もありますが、ここでは比phorを混ぜています。変数の概念はアルゴリズムとその意図に影響します—すべての変数がメモリ位置を持っていると仮定する必要はありません。一部の変数(特に配列)にはメモリロケーションがあります。これは、メモリロケーションがアドレス指定をサポートしているためです(CPUレジスタはインデックスなしでのみ名前を付けることができます)。

実行のために、変数とステートメントとプロセッサのメモリ位置とプロセッサ命令シーケンスの間には論理的なマッピングがあります。値が決して変化しない変数(定数など)は、値を自由に再現できるため(たとえば、コンパイラによって生成されたコードシーケンスの必要に応じて)、必ずしもメモリ位置を必要としません。


4
そして、8ビットのバイトでさえ普遍的ではありません。
デデュプリケーター

14
@JimmyJames forコンパイラーがループを完全に展開することを決定した場合、ループインデックスの場合を考慮してください。生成された出力コード(アセンブリ、マシンコード、またはバイトコード)のどこにも、ループカウンターが格納されるメモリの場所はありません。しかし、それはまだ変数です。
dmckee

4
@JimmyJames、展開されたループポインターの場合、はい、コードが実際にカウンターの値を使用する場合、どこかにロードする必要がありますが、(a)その場所はレジスターであり、(b)原則として、展開されたループのすべての繰り返しで同じ場所でなければならない理由はありません。
ソロモン遅い

3
ループが固定長配列sourceを等しい長さの配列にコピーするようなことをしている場合、ループは適切な回数の繰り返しに相当するものにコンパイルdestされるfor (int i=0; i<8; ++i) dest[i] = source[i];可能性がありますdest++ = source++;。ループカウンター自体は証拠のどこにも(レジスターにも)存在せず、繰り返しの数だけがループ状態について知らせます。
dmckee

2
区別は、メモリが番号付きの場所で構成されるマシンの抽象化に密接に基づいているセマンティクスのようなC言語のように多少混乱しています。
マイケルケイ

20

変数はメモリの場所と同じだと言っても安全ですか?

いいえ。変数とメモリの場所は、2つの異なる抽象化レベルの2つの抽象化です。変数とポインターはコード/言語レベルでの高レベルの概念であり、メモリロケーションはマシンレベルでの低レベルの概念です。コードが実行可能ファイルにコンパイルされると、変数はなくなります。この方法でメモリの場所と変数について話そうとすると、カテゴリエラーが発生します。

変数はメモリを使用して実装できますが、常にコンパイラが計算を最適化し、変数に関連するすべての計算をレジスタで完全に実行できる、または単一の変数を複数のメモリ位置に配置できる、または単一のメモリを使用できるとは限りません複数の変数の場所。

ポインタは、値が別のメモリ位置のメモリアドレスであるメモリ位置です。

この一連のフラッシュカードは非常に混乱しているため、正しくないだけでなく、間違っていることすらありません。


1
Once a code had been compiled into an executable, there's no longer any variables.それは私が間違いなく反対するものです。あなたが知っている変数(つまりその名前で)がもはや存在しないことは正しいですが、言い回しはコンパイルされた実行可能ファイルはメモリアドレスのみを使用することを示唆しているようです。それは正しくありません。コンパイルされているが実行されていない実行可能ファイルには、実行時に使用するメモリアドレスがわかりません。変数の概念(つまり、実行時に割り当てられるメモリアドレスへの再利用可能な参照)は、コンパイルされた実行可能ファイル内にまだ存在しています。
Flater

2
または、コンパイラはさまざまな方法で変数を完全に最適化できます。何かを事前に計算し、不要な変数を削除します。変数が定数である場合、コンパイラーは定数を使用するCPU命令を使用することになり、変数がどこにあるとしてもカウントされなくなると主張します。
kutschkem

16

変数は言語構造です。それらは名前を持ち、スコープ内に存在し、コードの他の部分から参照される場合があります。これらは論理エンティティです。コンパイラは、観察可能な動作が言語標準で規定されているものである限り、この言語構​​成を自由に実装できます。そのため、コンパイラーが必要でないことをコンパイラーが証明できれば、変数をどこにでも保存する必要はありません。

メモリの場所はハードウェアの概念です。仮想/物理メモリ内の場所を示します。すべてのメモリロケーションには、1つの物理アドレスと、それを操作するために使用できる任意の量の仮想アドレスがあります。ただし、各メモリ位置には常に正確に1バイトが保存されます。

ポインタは特別な種類のです。何かをポインターと言うのは、何かがタイプであると言うのに似ていますdouble。値に使用されるビット数とそれらのビットの解釈方法を示しますが、この値が変数に格納されることも、この値がメモリに格納されることも意味しません。


Cの例を挙げると、2D配列がint foo[6][7];あり、その要素にでアクセスするとfoo[1][2]foo配列を保持する変数になります。fooこのコンテキストで使用される場合、配列の最初の要素へのポインタになります。このポインターはどの変数にも格納されず、メモリにも格納されません。その値はCPUのレジスター内でのみ生成され、使用されてから忘れられます。同様に、foo[1]このコンテキストでは式は別のポインターに変わります。これも変数ではなく、メモリーに保存されず、CPUで計算され、使用され、忘れられます。3つの概念、変数メモリ位置、およびポインターは、実際には3つの異なる概念です。


ところで、私は本当に「各メモリロケーションに格納されているのは常に正確に1バイトである」ことを意味しました。これは、約50年前のコンピューティングの石器時代には当てはまりませんでしたが、今日使用されているほぼすべてのハードウェアに当てはまります。1バイトよりも大きい値をメモリに保存するときは常に、実際にはいくつかの連続したメモリ位置を使用しています。すなわち(ビッグエンディアンのバイト順と仮定して)数値0x01234567は次のようにメモリに保存されます

+------+------+------+------+
| 0x01 | 0x23 | 0x45 | 0x67 |
+------+------+------+------+
    ^      ^      ^      ^
    |      |      |      |
 0x4242 0x4243 0x4244 0x4245

(X86アーキテクチャのようなリトルエンディアンマシンは、バイトを逆順で格納します。)これは、ポインターにも当てはまります。64ビットマシン上のポインターは、それぞれ独自のメモリアドレスを持つ8つの連続したバイトに格納されます。メモリセルを見て、「ああ、これはポインタです!」と言うことはできません。メモリを見ると、常にバイトしか見えません


連続するメモリロケーションのグループがいつ開始および終了するかをコンピューターはどのように知るのですか?
プログナー

6
@prognerありません。それは解釈し、それが取得する指示に従ってメモリ内のバイトを。これらの命令も、一連のバイト自体にのみ格納されます。CPUにとって、命令を保持するバイト、文字を保持するバイト、および浮動小数点ビットを保持するバイトの唯一の違いは、このバイトを使用するように指示された方法です。プログラムカウンターがポイントしているためにバイトがフェッチされると、そのバイトは命令として使用されます。命令がそれをフロートレジスタにロードするように指示したためにフェッチされた場合、それは浮動小数点データとして使用されます。
cmaster

7
@prognerこれは、実際にはフォン・ノイマンアーキテクチャの重要な革新でした。命令とデータの両方を同じメモリに保存し、命令が後で命令として実行されるデータを変更できるようにします。これにより自己修正コードが可能になりましたが、システムのカーネルがプログラムをメモリにロードし、そのプログラムを実行するようCPUに指示することもできます。フォン・ノイマン以前は、Zuseマシンのようなコンピューターは、操作対象のデータから完全に独立したチャネルを介して指示を取得していました。
cmaster

5

あなたの実際の質問に焦点を当てましょう- 「だれが正しいですか?」これら2つのステートメントを比較する場合:

  • ポインターは、値が別の変数のメモリアドレスである変数です
  • ポインタは、値が別のメモリ位置のメモリアドレスであるメモリ位置です。

これに対する答えはありません。最初のものは「別の変数のメモリアドレス」について述べていますが、他の回答がすでに説明したように、変数には必ずしもメモリアドレスがありません。2つ目は「ポインターはメモリー位置です」と言いますが、ポインターは文字通り単なる数値であり、変数に格納できますが、前述のように、変数は必ずしもメモリーアドレスを持っているとは限りません。

より正確なステートメントの例:

  • 「ポインタは、メモリロケーションのメモリアドレスを表す数字です」、または

  • 「ポインタ変数とは、値がメモリロケーションのメモリアドレスである変数です。」

  • 「メモリアドレスは、メモリロケーションのメモリアドレスを表すポインタを保持できます。」

「ポインタ」という用語は「ポインタ変数」のショートカットとして使用されることがありますが、混乱を招かない限り問題ありません。


ポインタはそれ自身を指すことができるため、「another」を「a」に変更できます。
ピーターB

@PieterB:nitty、nitty ;-)これが本当に明確になるかどうかはわかりません。元の言葉遣いを実際に意味のあるものにするために必要な程度にだけ変更したかったからです。しかし、悲しいかな、私は編集を行いました。
Doc Brown

公平を期すために、「ポインターは文字通り単なる数字である」ということも正しくない場合、実際にはポインターは数字を参照する識別子です;)または少なくともこれらに入れる言語の詳細を知っていなければなりませんでした詳細。
ザイビス

2
ポインターは、潜在的に何らかのオブジェクトを参照する値です(数値は一部の実装に対して既に特定すぎています)。nullポインター、ワイルドポインター、およびぶら下がりポインターも存在する可能性がありますが、それらの一部(またはすべて)が使用言語によって除外される場合があります。
デデュプリケーター

2
@Deduplicator:あなたは正しいですが、数値としてのポインターのメンタルモデルは、この質問の目的には十分だと思います。それでは、物事をシンプルにしましょう。
Doc Brown

5

私は確かに、ポインターがアドレスを含むメモリ位置であるとは言いません。1つ0x23453は、1バイトに収まるアーキテクチャを知らないことです。:)バイト/ワードの区別を手放しても、すべてのメモリロケーションにアドレスが含まれるという問題があります。アドレスは単なる数字であり、メモリの内容は単なる数字です。

ここでの秘theは、「ポインタ」が人間の意図を説明するものであり、アーキテクチャの特定の機能ではないことだと思います。これは、「文字」または「文字列」がメモリで見ることができる具体的なものではないことに似ています。これらはすべて単なる数字でもありますが、文字列として機能します。「ポインタ」とは、単にアドレスとして使用することを目的とした値を意味します。

正直なところ、あなたの目標が特定の言語(Objective C?)を教えることである場合、古典的なメモリテープを引き出すことはそれでも有用であるかどうかわかりません。型付きの値と1バイトには大きすぎる値を表示することで、すでに白い嘘をついています。メカニズムではなくセマンティクスを教えます—ポインターに関する重要な洞察は、間接性を提供することです。これは理解するのに非常に有用なツールです。

良い比較はURLと比較することだと思います。URLは、データの場所を示します、データそのものではありません。私を聞いてください:

  • あなたはめったにURLが実際に何を気にしないです。それらの大部分は、名前付きのリンクで逃げています。多くの人々は、URLがページをどのように生成するを正確に知らずにインターネットを使用します。一部の人々は完全にURLを忘れています。

  • すべての文字列がURLであるわけではなく、URLとして使用されることを意図したものでもありません。

  • 偽のURL、または以前は存在していたがその後削除されたページにアクセスしようとすると、エラーが発生します。

  • URLは、画像、テキスト、音楽、または他の任意の数の個々のアイテムを指している場合があります。または、さまざまなものが含まれているページを指している場合があります。レイアウトは似ているがデータが異なるページ全体が非常に一般的です。

  • Webページを作成し、他のWebページのデータを参照する場合、すべてをコピーして貼り付ける必要はありません。リンクを作成するだけです。

  • 他のページをいくつでも同じURLにリンクできます。

  • 同様のページのコレクションがある場合、すべてのページへのリンクをリストするインデックスページを作成するか、ページ1の下部にページ2に移動する「次の」リンクなどを作成します。特にさまざまな場所でページを追加または削除するためにウェブマスターが何をする必要があるかを考慮する場合、両方のアプローチの長所と短所はすぐに明らかになります。

この類推により、ポインターの目的非常に明確になります。これは、ポインターを理解するために重要です。そうでないと、ポインターは arbitrary意的で複雑で無意味に見えます。何かがどのように機能するのか、そしてなぜそれが有用であるのかを既に理解していれば、何かの仕組みを理解するのははるかに簡単です。あなたは既にポインタが何か他のものがどこにあるかを示していますいくつかのブラックボックスであることに内在しました、とした場合、その後、あなたがメモリモデルの複雑さを学び、その後、アドレスとしてポインタを表すことはかなり明白です。さらに、セマンティクスを教えることで、学生は他の形式の間接参照を理解および発明するためのはるかに良い場所に配置されます。これは、ほとんどの主要言語にポインタがない場合に便利です。


every memory location contains an address-すべてのメモリロケーションはアドレスあります。多分ポインタ変数の中を除いて、どこにも含まれていません
ロバートハーベイ

@RobertHarveyにはすべてのメモリ位置(少なくとも単語)に数字が含まれており、これはアドレスとして簡単に解釈できます。ポイントは、ハードウェアで何が実際に非アドレスからアドレスを区別しないということだった
イーブイ

2

あなたはすでに答えを受け入れており、この質問にはすでに5つの答えがありますが、言及していない点があります。CSの教科書は、プログラミング言語の選択にとらわれないことが多いため、物事の説明に使用される用語は普遍的であるという暗黙の仮定につながります。そうではありません。

Cでは、単項アンパサンド演算子は「アドレス」演算子と呼ばれます。Cプログラマーは、式&xが変数xのアドレスに評価されることをためらうことはありません。もちろん、それらは「変数xの値が格納されているメモリアドレス」を意味しますが、カジュアルな会話では誰もその教訓的ではありません。Cでは、「ポインタ」という語は通常、値としてメモリアドレスを持つことを目的とした変数のデータ型を指します。または同等の値のデータ型。しかし、値そのものとして「ポインター」を使用する人もいます。

Javaでは、オブジェクト型または配列型のすべての変数はCポインター(ポインター演算を除く)とよく似ていますが、Javaプログラマーはポインターではなく参照と呼びます。

C ++は、参照とポインターを異なる概念と見なします。これらは関連していますが、まったく同じものではないため、C ++プログラマは会話を区別する必要があります。アンパサンドは、一部のコンテキストでは「アドレス」、他のコンテキストでは「参照先」として読み取られます。

ポインタは、値が別の変数のメモリアドレスである変数です。

これが、Cプログラマーが「int」と同じ意味で「ポインター」を使用して記述する方法です。(たとえば、「ポインタはメモリアドレスを保持し、intは特定の範囲内の整数を保持します。」)

ポインタは、値が別のメモリ位置のメモリアドレスであるメモリ位置です。

それは奇妙な言い方です。なぜなら、「is」の非常に緩やかで非公式の定義が必要だからです。

変数はメモリの場所と同じだと言っても安全ですか?

メモリアドレスは、変数の値が格納されるメモリ内の場所であると言う方が明確です。(コンパイラの最適化により、すべての変数がメモリに格納されるわけではありませんが、アドレスが取得される変数はすべて格納され&xます。)


私たちが行しているように:何かが保存されているアドレス。アドレスが何も保存できないことは別として、多くの場合、物は複数の隣接した場所に保存されますが、そのうちの1つだけが(ある程度一貫した規則によって選択されます)アドレスされます(そして潜在的に多くのアドレスの1つのみを使用します)。
デデュプリケーター

@Deduplicator私は1つは物足りにしようとしていません。
ガトキン

C規格は、正式に、すべての「シーケンスポイント」で抽象マシンのステップに厳密に従う必要がある変数と、スレッドセーフおよびメモリマップハードウェアでの特定の低レベル操作を区別します。 t、自由にレジスタに移動するか、完全に最適化してください。
デイビスラー

@Davislor:C標準では、他の言語仕様が「変数」を使用する場所で「オブジェクト」という用語を使用し、変数ではない他のことを記述しています。一部の説明では、言語に依存しない用語「変数」を使用する場合がありますが、何らかの理由で、標準には、名前付きのばらばらの割り当て(変数)をネストされた割り当て(構造体/ユニオンメンバー)や生成された名前のないオブジェクトなどの他の種類のオブジェクトと区別する用語がありませんポインターの逆参照。非公式には、「変数」は素晴らしい用語ですが、規格では使用されていません。
スーパーキャット

@supercatそれは正しくありません。C11標準では、「変数」という用語が100回以上使用されていますが、そのうちの数十は名詞です。例えば、「アトミック操作を介した初期化中の変数への同時アクセスは、データ競合を構成します。」
Davislor

1

ステートメントAポインターは変数であり、その値は別の変数のメモリアドレスが単純化されています。しかし、読者がメモリの場所が何であるか、そしてそれが変数とどのように異なるかを理解する頃には、ポインタが何であるかをすでに理解しているため、この不正確な説明に頼る必要はなくなります。

ステートメントAポインタは、値が別のメモリ位置のメモリアドレスが間違っているメモリ位置です。ポインタの値はメモリ位置に保存する必要はなく、「メモリ」の定義に応じて、ポインタがメモリ位置を指す必要があるかどうかは議論の余地があります。

変数とメモリ位置の違いは何ですか

メモリロケーションは、データを保存できる複数の場所の1つです。そのデータは、変数または変数の一部にすることができます。変数はデータにラベルを付ける方法です。


0

この回答は、CおよびC ++に焦点を当てています。あなたの質問は他の言語よりもC / C ++のより重要な部分であるポインターに関係しているので、それは適切だと思われます。この投稿の大部分は、精巧な実行時間のないほとんどのコンパイル済み言語(PascalやAdaなどですが、JavaやC#とは異なります)に適用されます。

既に与えられた良い答えは、変数が物理的記憶よりも抽象的なレベルの言語構造であることを強調しています。ただし、この抽象化には一定の根拠とシステムがあることを強調したいと思います。

抽象化は、主にリテラルアドレスの代わりに名前を使用することにあります。

基本的な考え方は、変数は型付きオブジェクトの名前付きハンドルであるということです。C / C ++のオブジェクトは通常メモリ内にあります。その後、言語は、型変換のためのライフタイム管理とデータマーシャリングに関するいくつかの機能を追加します。変数の概念は物理アドレスよりも抽象的です。これは、実際にはアドレスの数値やメモリ内の関数の正確な位置を気にしないからです。単純に名前を付け、後で名前でアドレス指定します。コンパイラ、リンカ、およびランタイムシステムがザラザラした詳細を処理します。

そして、C / C ++がメモリにとらわれないふりをしないでください。結局のところ、普遍的に適用可能なアドレス演算子があります。はい、本当です。レジスタストレージクラスでC変数のアドレスを取得することはできません。しかし、最後に使用したのはいつですか?これは一般的な概念の特別な例外であり、議論の全面的な却下ではありません。一般的な規則は、反対に、変数のアドレスを取得すると、コンパイラーが実際にメモリ内にオブジェクトを作成することを強制します。「名前付きハンドル」の概念は、C ++参照の優れたパラダイムでもあります。参照は、同じオブジェクトの単なる別の名前です。

68kのインラインアセンブラを書いたとき、アドレスレジスタへのオフセットとして変数名を使用する方法がわかりました(そしてregister、ベアメタルレジスタ名の代わりに宣言された変数の名前を使用できる!)。コンパイラにとって、変数は定数アドレスオフセットです。繰り返しますが、変数は名前付きハンドルで、通常はメモリ内のオブジェクト用です。


ポインターは、C#、Java、JS、およびその他の言語の非常に基本的な部分です。それらを異なる方法で呼び出しても、それは変わりませんが、良いPRです。
デデュプリケーター

@Deduplicator :-) Good ol 'Tony ...
ピーター-モニカの復職

0

質問は、C規格に追加の保証を追加することによって形成された一般的な言語を対象としているように聞こえます。 、前の部分が優勢です。」、および他の言語の用語の使用と一致する「変数」の定義。

その言語では、各メモリロケーションは、常にいくつか(通常8)のビットを保持する番号付きメールボックスとして表示でき、各ビットは個別に0または1にすることができます。メモリロケーションは通常、2、4、または8行で構成されます。また、いくつかの操作は、複数の連続したメモリロケーションを一度に処理します。マシンによっては、2、4、または8つのメモリロケーションのグループで動作する一部の操作が、単一行内のロケーションでの操作に制限される場合があります。さらに、一部のマシンには連続した番号のメールボックスの単一の部屋がありますが、他のマシンには番号の付いたメールボックスの複数のばらばらのグループがあります。

変数は、それに排他的に関連付けられているメモリロケーションの範囲と、それらのメモリロケーションが解釈されるタイプを識別します。変数を読み取ると、関連付けられた格納場所内のビットが変数のタイプに適した方法で解釈され、変数を書き込むと、関連付けられたビットがそのタイプと値に適した方法で設定されます。

アドレスは、メールボックスを識別するために必要な情報をカプセル化します。これは、単純な番号として、またはそのグループ内のメールボックスの番号とともに何らかの種類のグループ指定子として保存できます。

&演算子を変数に適用すると、アドレスとその型をカプセル化するポインターが生成されます。単項演算子*または[]演算子をポインターに適用すると、カプセル化されたアドレスから始まるメールボックスのビットが、カプセル化されたタイプに適した方法で解釈または設定されます。


質問を考え過ぎているように聞こえます。
ロバートハーベイ

0

私はこのパーティーに遅刻していますが、2セントを入れることに抵抗することはできません。

これらの時間で、これらのメモリ位置に保存された値の違いは何ですか?

時間1

ここに画像の説明を入力してください

時間2

ここに画像の説明を入力してください

正解:何もありません。それらはすべて、それらの意味の異なる解釈で提示される同一の値です。

どうやってそれを知るのですか?私がこれを作った人だからです。あなたはまだそれを本当に知りません。

あなたは、私が帯域外問題と呼ぶ何かに出くわしています。これらの値の意味を正しく解釈する方法はここには保存されていません。その知識は他の場所に保存されます。しかし、これらの価値を紙に提示するとき、あなたはその解釈に入れます。つまり、これらのメモリロケーションには存在しない情報を追加したことになります。

たとえば、ここの値は同じですが、ASCII / UTF-8文字エンコードがEBCDICと言うのではなく最初の文字エンコードであると仮定したときに正しい場合にのみ、真であることがわかります。また、2番目のものは、メモリロケーションに格納されている数値の16進表現であり、すべてが「0x」で始まる文字列への参照ではなく、他のアドレスへのポインタであると想定する必要があります。:P

これらのメモリ位置に保存されているものは、これらの仮定が正しいことを示すものではありません。その情報は保存できます。ただし、他の場所に保存されます。

これがプレゼンテーションの問題です。最初に番号を提示する方法に同意しないと、番号をまったく表現できません。仮定、慣習、コンテキストに頼ることができますが、プレゼンテーションを明示的に定義していないときに深く掘り下げた場合、唯一の正しい答えは「情報が不十分」です。


同じメモリを異なる一定のものに同時に使用すると、さらに楽しくなります。
デデュプリケーター

@Deduplicator True。それは常にc ++の再解釈キャストを考えるようになります。同じビットが異なる方法で見られました。
candied_orange

@Deduplicatorまたは、考えて
みると
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.