[解決済み] C言語のポインタ(宣言と単項演算子)を初心者にどう説明するか?
質問
最近、C言語プログラミングの初心者にポインタを説明する機会があったのですが、次のような難しさにつまずきました。ポインタの使い方を既に知っている人は全く問題に感じないかもしれませんが、次の例を冷静に見てみてください。
int foo = 1;
int *bar = &foo;
printf("%p\n", (void *)&foo);
printf("%i\n", *bar);
全くの初心者にとって、この出力は驚くべきものかもしれません。2行目で彼/彼女は *bar を &foo と宣言しましたが、4行目で *bar は &foo ではなく実際に foo であることが判明しました!
この混乱は、* 記号の曖昧さに起因していると言えるかもしれません。2行目ではポインタを宣言するために使用されています。4行目では、ポインタが指す値を取得する単項演算子として使用されています。2つの異なるもの、そうですか?
しかし、このquot;説明"は、初心者の助けには全くなりません。微妙な食い違いを指摘することで、新しい概念を導入しているのです。これでは、正しい教え方とは言えません。
では、カーニガンやリッチーはどのように説明したのでしょうか。
<ブロッククオート単項演算子 * は、インダイレクトまたはデリファレンス演算子です。ポインタに適用すると、ポインタが指すオブジェクトにアクセスするようになります。[...]
ポインタipの宣言です。
int *ip
はニモニックとして意図されたもので、これは式
*ip
が intであることを示します。
変数の宣言の構文は、その変数が現れる可能性のある式の構文を模倣しています。
.
int *ip
は"のように読みます。
*ip
は
int
を返すのでしょうか?しかし、それではなぜ、宣言後の代入はそのパターンに従わないのでしょうか?初心者が変数を初期化したい場合はどうすればいいのでしょうか?
int *ip = 1
(読みます。
*ip
は
int
と、その
int
は
1
を含む)は期待通りに動作しないでしょう。概念モデルが首尾一貫していないように見えるだけです。私はここで何かを見逃しているのでしょうか?
編集する それは にまとめています。 .
どのように解決するのですか?
の意味を理解するために
*
記号の意味を理解するためには、まず文脈が実際に異なることを理解する必要があります。いったん文脈が異なることを理解すれば(たとえば、課題の左辺と一般的な表現の違い)、その違いが何であるかを理解するのはそれほど認知的に飛躍したことではありません。
まず、変数の宣言に演算子を含めることができないことを説明します (これを示すために、変数に
-
または
+
の記号を変数宣言に使用すると、単にエラーになります)。次に、式(つまり代入の右側)が演算子を含むことができることを示しましょう。式と変数宣言は完全に異なる文脈であることを学生に理解させるようにします。
文脈が異なることを理解させたら、次に
*
記号が変数宣言の中で変数識別子の前にある場合、それは「この変数をポインタとして宣言する」ことを意味します。次に、式の中で(単項演算子として)使用する場合は
*
記号は「参照解除演算子」であり、以前の意味ではなく「のアドレスの値」を意味することを説明できます。
生徒を本当に納得させるために、C言語の作成者は参照解除演算子を意味する記号を使うことができたと説明してください(つまり、彼らは、参照解除演算子として
@
を使うこともできたが、何らかの理由で
*
.
結局のところ、文脈が違うということを説明しても、どうしようもないのです。文脈が違うことを理解していない生徒は、どうして
*
記号が異なるものを意味することができる理由を理解することができません。
関連
-
C - 添え字の値が配列でもポインタでもベクトルでもないエラー
-
[解決済み] C言語でchar配列をコピーする方法は?
-
[解決済み] C言語のコードで「:-!」とは何ですか?
-
[解決済み] 難読化Cコードコンテスト2006。sykes2.cの解説をお願いします。
-
[解決済み] 演算子 *, /, +, -, % を使わずに 3 で割る。
-
[解決済み] printfにおけるdoubleの正しい書式指定子
-
[解決済み] char s[]とchar *sの違いは何ですか?
-
[解決済み] ストラクチャーとユニオンの違い
-
[解決済み] LD_PRELOADのトリックとは何ですか?
-
[解決済み】C言語の関数ポインタはどのように機能するのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
g++が内部・外部コマンドソリューションとして認識されない、MinGWを初めて使うときの落とし穴
-
警告:代入がキャストなしで整数からポインタを作成する場合の修正方法に関する警告
-
error: 'for' loop initial declaration is only allowed in C99 mode 原因と解決方法
-
未定義の `__isoc99_sscanf' への参照
-
[解決済み] stdinとSTDIN_FILENOの違いは何ですか?
-
[解決済み] Linux Socket write() によるBad File Descriptor C
-
[解決済み] ++iとi++の違いは何ですか?
-
[解決済み] printfは、フォーマット文字列の中に改行がないと、呼び出し後にフラッシュしないのはなぜですか?
-
[解決済み] C言語標準に準拠した構造体の初期化方法
-
[解決済み】ポインターを理解するための障壁と、それを克服するためにできることは?[終了しました]