web-dev-qa-db-ja.com

ポインタの良い説明は何ですか?

あなた自身の研究(あなた自身で、またはクラスのために)で、最終的に、ポインタを本当に理解したときに「あはは」の瞬間がありましたか?初心者プログラマーに特に効果的な説明をお持ちですか?

たとえば、初心者が最初にCでポインタに遭遇したとき、コンパイルするまで&sと*sを追加するだけです(私自身が一度行ったように)。多分それはあなたやあなたの学生のためにポインターを「クリック」させた絵または本当にやる気のある例でした。それは何でしたか、それがうまくいかないようになる前に何を試しましたか?トピックの前提条件(構造体、配列など)はありましたか?

つまり、&sと*の意味を理解するために、それらを自信を持って使用できるようにするには何が必要でしたか。構文や用語、またはユースケースを学ぶだけでは不十分で、ある時点でアイデアを内部化する必要があります。


更新:これまでのところ私は本当に答えが好きです。来てください。ここには多くの素晴らしい見方がありますが、多くは私たちにとって良い説明/スローガンだと思いますコンセプトを内部化しました。それがあなたに気づいたときの詳細なコンテキストと状況を探しています。

例:

私はCでポインタを構文的に少ししか理解していませんでした。2人の友人が別の友人へのポインタを説明するのを聞いたのですが、structがポインタで渡された理由を尋ねられました。最初の友人はそれをどのように参照および変更する必要があるかについて話しましたが、それは私を襲った他の友人からの短いコメントでした:「それはまた、より効率的です。」 16バイトではなく4バイトを渡すことが、私が必要とした最後の概念的なシフトでした。

72
Macneil

グリッドとしてのメモリの図

通常、私が行うのはメモリを「グリッド」として表現することです。これにより、アドレスを作成し、さまざまなメモリ空間を強調表示して、セルの値(またはさらに、バイナリ表現)に書き込み、メモリ内のポインタをそれらの値にリンクできます。指す。 (そして、それでもそれは単純化であることを述べます)。

通常、それはほとんどの生徒にとって「おお」の瞬間です。

シンボルジャグリング

次に、&と*の使い方を忘れないようにするのは非常に簡単です。数学や物理学の計算と同じ方法で提示します。 km単位の距離を時間単位の時間で割ると、km/h単位の速度が得られます。何が入っているかを出す必要があります。シンプル。

レスキューへのprintf

これらで説明した内容を視覚的に表すいくつかの基本的な例を実行するだけで、彼らが理解したと思われるもので彼らを慰めるか、または「ああ、私はこれを取得しない」と言う機会を与えます。

広範囲に

単純型のポインタをカバーし、データ型のアドレス指定とサイズ、構造体、配列、および複数のレベルの違いを理解するようにします。

次に、ポインタ演算を開始します。


補遺:再帰

私は通常、視覚的表現を使用して、再帰を同様に説明します。単一の文字を書き込む既成の関数を使用してアルファベットを印刷し、2行を変更するだけで逆の順序で印刷するように依頼します。

通常、「何を...」というものがあります。そして、もう1つのパラメーターをprintfに追加して数値を出力し、ステップをインデントすると、それは安堵のため息になります。


代替案:Play-Dohモデルとウォーターカップ

実際、私には大学の同僚が何人かいて、play-dohペーストを使用してポインタとメモリアクセスを説明するビデオを学生に見せました。プログラミングを理解することに興味のある非常に若い学習者を除いて、私は実際には自分でそのテクニックを使用したことはありませんが(通常、ポインタを使用して言語に早すぎることはありません)、それは信じられません。基本的に、メモリスペースを表す他のより大きなplay-dohのボールに接続できる小さなplay-dohのボールを使用し、それらを結合して(リンクされたデータ構造のように)リンクするか、または(隣接するように)一緒にマージすることができますメモリ空間)。指すメモリ空間に異なる色を使用すると、ポインタも役立ちます。ただし、ポインティングが「マップ/グリッド」の場合のように、実際には「アドレス指定」の問題であることを明確に示すことができるので、Memory-as-a-Gridの方がうまく機能すると思います。一方、Play-dohモードでは、物事はメモリ内で実際に互いに「触れ合う」と考えるのを混乱させます。

ウォーターカップのものも同僚によって直接使用されましたが、彼女がそれを思いついたかどうかはわかりません。面白いアプローチでしたが、説明に戸惑っている生徒が多いことに気づきました。 DevSoloのコーヒーカップテクニックに似たもの 。しかし、学生がコンテナ、データ構造、ポインタ、配列を混乱させるので、それは実際には誤解を招くものだと思います。私が想定している最初に配列を説明するのは興味深いアプローチかもしれませんが、あまり長くは固執しません。

25
haylem

私がかつて言ったよりもはるかに賢い誰か:

尼僧呉Jinkangは第6愛国者Huinengに尋ねました、「私は何年もの間Mahaparinirvana経を研究しましたが、私が完全に理解していない多くの領域があります。私に啓発してください。」

愛国者は、「私は読み書きができません。文字を読んでください。意味を説明できると思います。」

修道女は言った、「あなたは文字を認識することさえできません。どうしてあなたはどうしてその意味を理解することができますか?」

「真実は言葉とは関係ありません。真実は空の明るい月に例えることができます。この場合、言葉は指に例えることができます。指は月の位置を指すことができます。しかし、指は月。月を見るためには、指を越えて注視する必要がありますよね?」

80
Frank Shearar

図が非常に役立つことがわかりました。例:

pointer diagram


この種の図は、ポインタが独自の変数であるが、別のオブジェクト、つまり配列や文字列の場所である値が含まれていることを理解するのに役立ちました。また、鉛筆で書くと、紙や黒板/ホワイトボードでプログラムをたどることができます。

46
Michael K

ポインタについて初めて「学習」したとき、私はそれに突き刺されたようなものでした。私の大学は、Javaを中心にカリキュラムを集中するように登録するずっと前に決定を下していたので、データ構造の教授がCについて1つの講義を行い、ポインターを使用してXORリストを実装するように依頼したとき、何かに入っているように感じましたway頭の上。

私は定義を理解しました:

ポインタは、変数のアドレスを含む変数です

しかし、私はまだ概念の大部分を理解していませんでした。振り返ってみると、それは3つのことに集中していると思います。

  1. 正確にははメモリの場所ですか? (当時、私はコンピュータ組織のクラスを受けていませんでした)

  2. ぎこちない構文(つまり、ええと...なぜ「int * ip」のように正確に定義されているのですか?その後、変数を「ip」と呼んでいますか?)

  3. 変数を使用するだけでなく、変数のアドレスを格納することの正確さはどの程度正確ですか?

私がK&Rの本を購入してすべての問題を完了するまでは、実際に指針をつかむことができませんでした。 Computer Organizationクラスを長い間完了しているという事実(Cを学ぶ前に必要だと思う)に加えて、関数、配列、構造体にポインターを使用できることに気付いたという事実もその一部でした...通常の変数のアドレスのストレージとしてだけでなく、有用なことを行うため。

しかし、私の「あは」の瞬間は、K&Rが単純なポインターを定義する厄介な構文を説明する方法でした。私は本全体を通してメモを取り(この本で私が理解を深めるために、自分の言葉にこの本の指摘を書き直しています)、これはそれに関連しています。

ポインターは、変数へのアドレスを含む変数です。ポインターは、 '*'演算子を使用して定義および逆参照(ポインターが指すメモリー位置に格納されている値を生成)の両方です。式はニーモニックです。

Ex.: 
   int a;      /* Variable 'a' is an integer */

   int *ip;   /* Variable ip is a pointer and dereferencing it gives an integer.
                 In other words, the expression *ip is an int, so ip is a pointer
                 to an int */

頭の中に何か素朴なものが浸透するまで、ポインタのより高度な概念を完全に理解することはできないといつも感じていました。その割り当て(ちなみに私はあまり上手ではありませんでした;)の後で、私は(*と思った) "* ip"を定義した直後に "* ip"が存在しなかった理由が際限なく気になりました。これをマスターすることは、関数ポインターなどのポインターや、次のようなより複雑な定義など、より高度な概念に不可欠です。

char (*(x())[])()

全体として、ポインタの概念には次のものが必要だと思います。

  1. コンピューターでのメモリのレイアウト(およびメモリとは)に関する基本的な知識。

  2. ポインタがどれほど強力であるかについての知識(学習のために学習する別の抽象的な概念ではなく、実際の使用法)。

  3. 通称「ポインタの定義」として知られる象形文字の解読

つまり、ポインタについて学ぶときは、少なくとも3つの「あは」の瞬間があると思います。私はまだ学生なので、まだ概念を学んでいない(比較的)新鮮な人の視点に感謝するでしょう。

32
Kevin

ポインタは、デスクトップ上のアプリケーションショートカットに少し似ています。ショートカットを削除しても、ターゲットはまだ存在しています。ショートカットを起動すると、ターゲットが起動します。

私はいつも、デスクトップ上にtxtファイルを作成し、ファイルへの2つのショートカットを作成することで、この作業を説明しています。ショートカットをコピーして削除した後、「参照」の背後にある考え方を人々が理解しているのを見ることができます。

グループがショートカットの背後にある基本を理解したら、必要に応じてポインタの説明を開始できます。彼らはおそらくそれをかなり簡単に理解するでしょう。

19
Barfieldmv

8-10年前、私はコミュニティカレッジでイントロ「C」コースを教えました。これは常に楽しいトピックでした。一番うまくいったように見えたのは、同僚と数回話し合った後のことで、コーヒーカップとあなたの手を使うことでした。

私はコーヒーカップ(または配列の場合はそれらの行)の類推を変数(何かを保持できる)として使用しました。次に、何かを持っているか、人差し指を伸ばしてコーヒーカップを「指す」ようにした手を使用しました。

近づいた手は空で、頭を指していた指(モックガンのように)はぶら下がったポインターでした。

次に、いくつかのデモンストレーションとデバッガーのトリップにより、ほとんどのクリックがありました。

14
DevSolo

「どのようにしてポインターを把握したのか」という質問を聞いたとき、私は本当に心配しました。コンセプトは信じられないほどシンプルで、プログラマーに大きな力を提供する言語の論理的な進化だといつも思っていました。

心配なのは、ポインターの概念を理解するのが難しいと思ったことがないことです。したがって、ここで「いつ最終的にそれを手に入れたのか」を何度も繰り返したとき、あなたは考え始めます。

私は実際にそれを得ますか?たぶん私はしたことがないのですか?

コンセプトがトリッキーなように思われるのは、ポインタを理解するのが難しいということを、私たちがまだ知らないすべての人に伝え続けているからです。

そのアイデアを捨てるだけで、もちろん個人的には私は良い図が大好きです Steve Gibsonは常に何でも説明するという素晴らしい仕事をしています

10
Marcus Whybrow

Cのポインターについては、それほど問題はありませんでしたが、それは、最初にアセンブラーを学習する必要があったためかもしれません。自分で住所を管理する必要がなくなったことは、本当に安心でした。ですから、多分答えは(これがあなたが教えているものだと仮定して)、生徒に動作させるためのエミュレートされたアセンブリ言語を与えることです。彼らはwill「こんにちは、世界」より洗練されたものを書く過程でそれを理解します。

7
Larry Coleman

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

7
kirk.burleson

ポインタについて実際にどのように学びましたか?単純なコンパイラの新入生の大学1年を書くことによって。

素人の言葉でポインターを説明するには?インデックスカードに保存されているライブラリカタログの(日付付き?)アナロジーが好きです。各カード(「ポインター」)には、書籍(「データ」)の場所に関する情報が含まれていますが、実際には書籍自体は含まれていません。カードを変更する場合(「ポインター演算」)、カードが指す本を変更するだけで、本自体には影響しません。住所を間違えないように注意してください。存在しない本を指す可能性があります。または間違ったライブラリです。ただし、カードの「住所」に従ってライブラリの適切な部分に移動すると(「ポインタを逆参照」)、書籍自体を表示または変更できます。

6

質問の改訂された要件をサポートするために編集されました

「ポストポインター」を理解するための私のパス(正しく思い出せば)は次のようになりました。まだ BBC Micro をいじくり回しているときから、アセンブリプログラミングの簡単な経験があったので、メモリの概念を箱の束として持っていました(これについては以下を参照)。これは、配列の使用によって強化されました。しかし、私はCの世界に入り、文字列を処理する必要があり、それはポインタを意味していました。 BASICではこれは取るに足らないことでしたが、アセンブラではそれらを操作する必要がありませんでしたが、今ではクラシックCではすべてのポインタやものです。ああ、でも、次のように(nullで終了する)文字列を含む配列に切り戻すことができます。

char s[] = "Hello, world!";
printf("%s",s);

結局のところ、これは文字の配列(私の小さな世界では1文字あたり8ビット)であり、末尾にゼロ文字があり、どこで終了するかを示しています。 printfはその配列を受け取り、それを実行して印刷します。しかし、この文字列を関数に渡したい場合はどうなりますか?

void print_str(char* p) {
  printf("%s",p);
}

マニュアルには何が書いてあるのですか?それは何ですか*すべてについて?うーん、char *は「charへのポインター」を意味します。わかりました...私を失いました。それから、char *がpをs [0]と等価にすることが私に気づきました。はい、それを使用できますが、ポインターが何であるかはまだわかりません。つまり、これらのいずれかを使用してデータを設定するにはどうすればよいですか?再びマニュアルに...

char* p = "Hello World!";

上記を書いているとき、私は「charへのポインターを宣言し、それをこの文字の配列と等しくなるように設定する」と自分に言っています。どういうわけか、そのポインタは配列の必要性をなくします。それはコンパイラが変更のために私のために何かをしていると思います。それで、このポインタで配列をどのように変更できますか?アレイバージョンを使用できることを知っています

 s[2] = 'L'; 

しかし、「ポインターが話す」で同等のものは何ですか?再びそのマニュアルに...

*(p+2) = 'L';

*は単に「メモリアドレスの内容」を意味し、(p+2)s[2]。これは、ポインタpが...ただ...、...、アドレス...だったことを意味します!

悟りの音があること。私は突然ポインターを小刻みに動かしました(それはずっと前のことですが、私たちの古いタイマーは遅くなるまで「鳴りません」でした)。それは単なる間接的なものでした。


元の:

OK、私の2cの価値:

メモリがたくさんの箱だと想像してください。各ボックスには、側面(住所)に番号が付いています。各ボックスには番号(内容)が含まれています。これらのボックスは、変数(ボックスNの内容が必要)、ポインター(ボックスの内容が必要ボックスNにあるもの)の2つの方法で操作できます。ポインタは単に間接的なものです。

そして、あなたが知る必要があるすべてをカバーする大きな答えのために- これを読んでください

5
Gary Rowe

ポインタを学習しようとしている人が、通常の変数とは何か、Cでどのように機能するかを知っていると想定します。次に、いくつかの属性を持つポインタを定義してみましょう-

  • これらも変数ですが、性質は異なります。変数空間に2つのレイヤーがあると仮定します。異なるタイプの通常の変数は、上位層にあり、ポインタは下位層にあります。この図のように

    alt text

  • 「ポインタ」という名前が示すように、ポインタは何かを指すことができます。私たちの指が何かのオブジェクトを指すことができるように。彼らが指すものは何ですか?これらは通常の変数です。要するに、「ポインタは通常の変数を指す」ということです。

  • 通常の変数と同様に、ポインターもint、char、floatなどの同じ数の型です。また、特定のタイプのポインターは、同じタイプの変数のみを指すことができます。
  • ポインターは1つの変数を指すことができ、後で同じポインターが別の変数を指すことができます。タイプだけが同じである必要があります。したがって、ポインタと変数の関連付けは永続的ではなく、変更することができます。
  • では、ポインタはどのように宣言されていますか?ほとんど通常の変数と同じです。名前の前にアスタリスク(*)を付ける必要があります。お気に入り-

    int *pointer;
    
  • では、ポインタはどのように変数に関連付けられているのでしょうか。このステートメントのような変数の前に&演算子を使用する-

    pointer = &variable;
    
  • 変数を指すことによってポインターはどのように使用されますか?これは、名前の前にアスタリスク(*)を付けることでも行われます。次に、現在指している変数の代わりに使用できます。

    *pointer = var1 + var2;
    

    の代わりに

    variable = var1 + var2;
    
  • ここで、いくつかのコードを使用してポインターを操作します。このポインタの特性に慣れるだけです。ここまでは、ポインターの機能について説明しました。問題がなければ、ポインタが変数を指している方法と、通常の算術演算がそれらに適用された場合のポインタの反応を調べます。次に、ポインタと配列、およびポインタへのポインタの関係を調べます。

ポインタの学習について、これでお勧めします。

5
Gulshan

木の小さなブロックをいくつか入手してください。

一方の端に金属製のフックを、もう一方の端に金属製の目を追加します。

これで、リンクされたリストを操作できるもので実行できます。

この物理的な小道具で説明してみてください。 1年生(新入生)の生徒へのポインタを教えるときに、これが欲しいとよく言っていました。

小さな金属製のフックがポインター、木のブロックが指しているものです。

私はブロックで遊んだ後にそれを取得しないように誰もを拒否します。

4
Tim Williscroft

私は綿毛をすべて取り除き、ポインターを魔法の実体ではなく、他の変数として扱い始めたとき(ずっと前の11年生のとき)、私は人生を楽にしてくれました。

  1. ポインターは、別の変数(または任意のアドレス)のアドレスを格納する変数です。
  2. *は、ポインタ変数に格納されているメモリ位置の値を取得するために使用されます。
  3. &演算子は、メモリ位置のアドレスを提供します。

残りは構文糖と常識です。いくつかの単純なCプログラム(リンクされたリストライブラリの実装など)をポインタを使用して記述し、こつこつとしましょう。

4
Sridhar Iyer

私が本当にうろたえた説明は:

いくつかの土地に建てられたさまざまな家がある都市グリッドを考えてみましょう。手に紙を持っている。あなたが書いた紙の上で:


デビッドの家、

112そうそう通り。


一枚の紙(ポインター変数)には、Davidの家へのpointsというアドレスが含まれています。友人にデビッドのかっこいい家を見てもらいたい場合は、実際の2階建ての建物を郵便で送るよりも、紙の小片を家への参照として使用する方がはるかに簡単です。

実際のポインタと同様に、紙のアドレスをたどると問題が発生する可能性があります。デビッドは動いていたかもしれません、そしてあなたがそこに着くとき、あなたはただ地面に大きな穴を見つけます。この場合、Davidが移動したときに紙の住所を消去するか、少なくとも新しい住所に変更した方がよいでしょう。また、住所に行って、友人のDavidのリビングルームだと思うものを入力することもできますが、今回は完全に見知らぬ人のプールに行き着きます。他の誰かがあなたが持っていたアドレスのスペースをまったく別のものに使用しました。

2
Per Wiklander
  1. ポインタは、インデックスを配列に一般化したものと考えることができます。
    • 大きな配列は、いくつかの小さな、重なり合わない、可変サイズの配列に分割できることを考慮してください。さて、これらの小さな配列は、私たちが通常配列と考えるものです。大きい方は、コンピュータの全メモリ空間です。小さな配列を切り取るプロセスは、メモリ割り当てと呼ばれます。
  2. いくつかのポインターによって一緒にリンクされている構造のセットは、 有向グラフ 。と考えることができます。
    • 各頂点は、いくつかの値を保持できる変数です。
    • 一部の変数はポインターであり、各ポインターは別の何かへの送信エッジを1つだけ持つことができます。
    • ポインターではない変数には、発信エッジがありません。それらは、任意の数の着信エッジを持つことができます。
2
rwong

ポインタについて説明したい場合は、まずメモリについて説明する必要があります。私は通常、行と列のある方眼紙/方眼紙を使用してそれを行います。 「学生」が記憶を理解すれば、彼女は住所が何であるかを理解することができます。あなたがアドレスを得たなら、あなたはポインタを得ました。

この抽象化で遊ぶことができます。例えば。 1つの正方形のアドレス(番号)を別の正方形に書き込みます。次に、ポインタの正方形から目的の正方形に矢印を描きます。次に、ポインタを上書きし(たとえば、インクリメント)、矢印を調整します。別の正方形に住所を書き込んで、生徒に矢印を描かせます...

次のステップ:特定の四角形(ポインターなど)に名前を付けます。これで、逆参照について説明できます。それでおしまい。

2
EricSchaefer

ポインタの周りの状況を完全に思い出すことはできませんが、cスタイルの配列に関する私の理解の周りの記憶をさかのぼって作り直しました。 (つまり、_arr[3]_は*(arr+3)と同じです)

何らかの理由で、ポインターの状況が発生したときに、ポインターを配列として表示することは非常に役立ちます。

2
Zaz

基本的に@Gary Roweは適切なモデルを導入しました。それらにアドレス(番号)が付いたボックスのセットとしてのメモリ。各ボックスには値(数値)が格納されます。

ポインターの考え方は、あるボックスの値を別のボックスのアドレスとして解釈することです。この値は、特定のボックスを参照するために使用されます。これが参照と呼ばれる理由です。したがってdereferencingは、参照されるボックスを開くプロセスです。

vが変数(ボックス)の場合、ステートメント

  • vvの値を意味します。つまり、ボックスの内容を教えてください
  • *vは、vの値を逆参照することを意味します。つまり、vの値によって参照されるボックス内の内容を取得します
  • &vは参照vを意味します。つまり、箱の住所を教えてください

ポインタをまったく別のものとして紹介するという目的にはかなわないと思います。子供の頃はなかなか理解しにくいコンセプトでした。それはいつも私が本当に理解できなかったいくつかの闇の魔法のように見えました、それは多くの特別なキャラクターを必要としました。初めて理解したのは、ポインタ演算を持たない言語で二重間接演算を使用する小さなゲームを書いたときでした。それが私を啓発しました。

ポインタは解釈の問題です。私はそれを説明することで物事がずっと簡単になると思います。また、10個の変数のメモリを持つ簡単な例を示すと、ポインタ演算は非常にシンプルで直感的な操作になります。

2
back2dos

多分それは私だけですが、私は類推でうまく機能します。それで、誰か(関数/クラス) "Bar"を他の誰かにしたい友達(関数/クラス) "Foo"がいて、何らかの理由で連絡したとします。 "Foo"は "Bar"を見に行くことができますが、それらすべての存在(インスタンス)を移動するのは不便です。ただし、「Foo」はあなたの電話番号(ポインタ)に「Bar」を送信できます。そうすれば、どこにいても、「フー」はあなたを見つけることなくあなたに連絡する方法を知っています。

そして、「バー」にあなたと連絡を取りたがっている「バズ」という知人がいるとします。しかし、あなたはあなたの電話番号を守っており、誰にも知られたくないのです。「Baz」は「Bar」(ポインターとしての電話)に電話をかけることができます。そして、「Baz」の友達や友達の友達の連鎖が続きます。

2
Hugo

アセンブリ言語やコンピュータアーキテクチャを学んだことがあれば、ポインタはwayの方が理にかなっています。 Cクラスを教える場合、メモリモデルとプロセッサが実際に実行する命令の種類を説明するために、2週間のアーキテクチャから始めると思います。

2
Barry Brown

私の「あはは!」このチュートリアルに来た瞬間:

Cのポインターと配列に関するチュートリアル

正確には、この章に含まれています。 第3章:ポインタと文字列

より正確には、次の文が付いています。

Puts()に渡されるパラメーターはポインター、つまりポインターの値です(Cのすべてのパラメーターは値で渡されるため)。ポインターの値は、ポインターが指すアドレス、または単にアドレスです。 。

私がそれを読んだとき、雲は分かれ、天使たちはトランペットのファンファーレを吹いた。

ご覧のとおり、私がそれ以前に読んだCのチュートリアルや本はすべて、Cが値渡しまたは参照渡しで悪質な嘘をつくことができると断言していました。真実は、Cは常に値で渡されることですが、渡される値がたまたまアドレスである場合があります。メソッド内では、渡されたintからコピーが作成されるのと同じように、そのアドレスからコピーが作成されます。コピーはnotから作成されますポインタが指す値。したがって、メソッド内でポインターを使用すると、元の値にアクセスして変更できます。

私はCプログラマーになりませんでしたが、.NETプログラマーになりました。オブジェクトとオブジェクト参照は同じように機能します。オブジェクトへの参照は値で渡されます(したがってコピーされます)が、オブジェクト自体はコピーされません。ポインタを学んだことがないため、これを理解できない多くのプログラマを回避してきました。

2
Kyralessa

ポインタは、何か便利な場所を示す付箋です。これは、モノの場所を含み、モノの大きさを示します(とにかくCで)。したがって、ダブルポインターは、「冷蔵庫に6個のパックがあります」という付箋のようなものです。それがコーラであるかバドワイザーであるかを理解するには、実際に6個のパックを入手する必要があります。

1
philosodad

http://cslibrary.stanford.edu/

このサイトには、ポインタとメモリ管理を学ぶための素晴らしいチュートリアルがあります。

ポインタの基本、ポインタ、およびサイトに記載されているメモリについて説明することをお勧めします。リンクに記載されているリンクリストの問題を参照して、ポインターの概念をさらに強化することもできます。

1
deovrat singh

コードを指定:

int v=42; //単純な変数の宣言と初期化

int *p = &v; //変数vにポイントpを作成する

上記のコードについて次のように言うことができます:

int * p // "int pointer p" ...これは、int型の変数へのポインターを宣言する方法です

*p //「pが指す」...これは、pが指すデータであり、vと同じです。

&v // "変数vのアドレス" ...これはpのリテラル値を表します

1
zener

ポインタを説明する鍵は、説明している人がメモリの概念をすでに理解していることを確認することです。メモリが大規模な配列として存在し、インデックスの位置によって配列内の任意の位置にアクセスできることを理解すれば、低レベルで本当に理解できればいいのですが。

次のステップは、メモリ全体をコピーするのではなく、インデックスの場所を渡すという概念を持つことは、ほとんどの人にとって理にかなっています。そして、ポインタが有用である理由をほとんどの人が理解できるようにするのに十分です。

ポインタを理解する最後のステップは、すべてのデータが格納されている場所のインデックスの場所を格納するメソッドのメモリインデックスの場所をパラメータとして渡す方法を説明することです。これは、一部の人々が対処するには遠すぎる可能性があることを発見しました。

誰かがこれらの基本的な手順を把握したら、実際のデータオブジェクトを見つけるためにアドレスを調べる必要がある回数を追跡している限り、ポインタを無制限にチェーンできることを理解するのは簡単です。

誰かがポインタを把握したら、次に把握しなければならない次のことは、ヒープメモリとスタックメモリの違いであり、スタックメモリへのポインタがメソッドの外部に渡されると危険である理由です。

1
Michael Shaw

トリックは、物事の場所と物事自体がパイプの絵のように同じではないことを説明することです パイプではありません 。モノを移動すると、その場所が変わります。場所は残っており、他に何かを置くことができます。

1
sal

あなたが少なくとも表面的なレベルですでに配列を理解していると仮定すると、ポインタについての私の最高の説明はこれです:

コンピューター内のすべてのメモリ(または、より正確にしたい場合はプロセス内のアドレス空間)を1つの巨大なバイト配列として想像してください。ポインターは、その配列への単なるインデックスです。したがって、ポインタは特別な種類の整数です。

Cおよびアセンブリのコーダーがポインターを整数として扱うことで実行できるすべてのトリック、およびその区別がアセンブリ言語レベルでの純粋な慣習である方法について学ぶことは、この理解を強めるのに役立ちました。

0
dsimcha

私が大学にいたとき、教授はポイントをそれ自体の個別の変数として、メモリの場所への矢印(配列のように表されます)で表している非常にきちんとしたPowerPointスライドをいくつか持っていました。矢印が変わるとき、ポインタが逆参照されるときなどを示す段階的に、数分以内にそれを理解できない方法はありませんでした。コンセプト自体は非常に簡単ですが、正しく実行するか、実際のプログラムに適用するには、さらに練習が必要です。

0
chiurox

その前に、プログラミングでは「すべてがメモリを使用する」ことと、メモリ内の(静的)変数の割り当てについて説明します。また、メモリアドレスとは何か、メモリ空間、メモリアドレス、変数の関係についても説明します。

最後に、整数データ型と変数、文字列データ型と変数などがあることを説明し、メモリアドレスを格納する、0 o ""のような空の値を持つ特別なデータ型があることを説明します。 nullと呼ばれます。

そして最後に、ポインタの使用を通じて動的に割り当てられた変数。

0
umlcat

「Cパズル」などの本を覚えています。これは、図書館で入手できるプログラミング/コンピューター関連の数少ない本の1つだったので、Cの理解は初歩的なものでした。それはあなたにCの表現を投げ、それを説明するように頼み、ますます複雑になりました。

0
peterchen