アカウント名:
パスワード:
p = &n; // pにnのポインタを代入
特定のアドレッシングルールに左右される「アドレス」という概念を、ポインタの説明に使わないほうがいい
おっしゃりたいことはなんとなく分かる気がします。でも、じゃあ、実効アドレスって言葉を使えばいいんでしょうか。確か6809のマニュアルで「アドレッシングがたくさんあるけど、アドレッシングの計算をした後、実際にアクセスされるメモリアドレス」の意味で用いられました気がします。(記憶があやふやですが。)じゃあ、「実効アドレス」と「アドレス」の違いって何?ってやりだすと先に進まない。現実的にCって、高級アセンブラという側面があるので、「アドレス」とポインタをはっきり分ける意味は薄いと思います。
ちなみに、niqueさんは「アドレス」という概念を使わずにポインタをどうやって説明したらいいと思いますか。私は、まずはフラットなメモリモデルで理解すれば十分だと思います。もちろん、その時に使うキーワードは「アドレス」です。:-)
# その理解で止まってもらうと大いに困るんですが。(笑
ACさんの発言とかぶる所があるのは申し訳ないです。
byte型のポインタであるアドレスではビット位置を表現することはできません。
それをポインタと呼ぶ現場があることは理解しますが、ビット位置まで特定できるポインタは標準C言語には用意されてません。言語拡張されてビット位置も指定できる処理系がものがあっても驚きませんが、niqueさんの使っている処理系はそういう拡張がされているんでしょうか。あ~でも、gccとかでそんな拡張がされていてもおかしくないかも。そんなこと使えると思わないから使わないから気がつかないという。(笑)
# まあ使えると知っていても積極的に使おうと思わないですが。
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
一つのことを行い、またそれをうまくやるプログラムを書け -- Malcolm Douglas McIlroy
CとC++ (スコア:1)
単に
int n; // 整数型変数nを定義
int *p; // 整数ポインタ型変数pを定義
n = 5; // nに5を代入
p = &n; // pにnのポインタを代入
*p = 10; // pがポイントする変数に10を代入
見たいに書けば間違いも起こりにくくわかりやすい気がするんですけど。
Re: (スコア:1)
あくまでも私の経験上の話です。
ここを
「pにnのポインタを代入」
と説明した人は、たいていポインタを正しく理解していませんでした。
一方、ここを
「pにnのアドレスを代入」
と説明した人は、全員ポインタを正しく理解できていました。
また、前者のポインタを代入と説明した人の中には
アドレスであることをふまえてあえて前者の「ポインタを代入」と説明する人がいました。
しかし、その人は値渡し/参照渡しの違いを正しく説明できませんでした。
Re: (スコア:1)
私の理解では、アドレスはポインタですけど、ポインタはアドレスじゃないです。
特定のアドレッシングルールに左右される「アドレス」という概念を、ポインタの説明に使わないほうがいい、と思っています。
概念としてのポインタは、アドレスのような特定の型の数値ではなく、アドレス空間変換メソッドを備えたクラスなんじゃないでしょうか。
ただ最初からその説明では、解説に手間がかかりすぎますよね。だから簡単な概念を示し、その説明を端的に行うこと、誤解を生まない工夫などが重要だと思った次第です。
私が言いたかったのは、最初の理解のためには宣言文と初期化代入文をいっしょにしないほうがいい、ということだけです。
ヌルポ対策やクラスとしてのポインタの理解は、次の段階でやればいいんじゃないでしょうか。
ポインタとアドレッシング (スコア:1)
おっしゃりたいことはなんとなく分かる気がします。でも、じゃあ、実効アドレスって言葉を使えばいいんでしょうか。確か6809のマニュアルで「アドレッシングがたくさんあるけど、アドレッシングの計算をした後、実際にアクセスされるメモリアドレス」の意味で用いられました気がします。(記憶があやふやですが。)じゃあ、「実効アドレス」と「アドレス」の違いって何?ってやりだすと先に進まない。現実的にCって、高級アセンブラという側面があるので、「アドレス」とポインタをはっきり分ける意味は薄いと思います。
ちなみに、niqueさんは「アドレス」という概念を使わずにポインタをどうやって説明したらいいと思いますか。私は、まずはフラットなメモリモデルで理解すれば十分だと思います。もちろん、その時に使うキーワードは「アドレス」です。:-)
# その理解で止まってもらうと大いに困るんですが。(笑
vyama 「バグ取れワンワン」
Re:ポインタとアドレッシング (スコア:1)
やっぱりポインタを教えるのにみんな苦労してるんでしょうね。
先の説明ではわかりにくかったかもしれませんが、ポインタとアドレスは等価じゃありません。
アドレスはCPUが扱える最小のメモリ単位です。この最小のメモリ単位というのはポインタで言うところの型に相当し、またその値の扱い方もポインタとおなじです。最小のメモリ単位が1バイトなら、つまりはアドレスはbyte型のポインタです。
一方、ポインタの指す場所はCPUが扱える最小のメモリ単位以下になる場合があります。通信関係の開発をするとよく出てくるビットパッキングされた構造体の内部要素のポインタが、その例としてはわかりやすいでしょうか。byte型のポインタであるアドレスではビット位置を表現することはできません。つまりポインタはアドレスではありません。
(あーこの説明もわかりにくいなあ、まだまだライター様にはなれそうにない・・・)
さらに説明する相手がメモリやCPUがそれをどのように扱うかなどの知識を持っていない場合、アドレスという言葉の定義から説明しなくてはなりません。
そこまでのコストをかけて、このように見方を変えると等価でない概念を同じものとして説明してしまうくらいなら、そうでない方法や言葉で説明したほうがいいんじゃないかと思っているのです。
じゃあ私がどうやって説明するのかと言うと、すでに他の方がおっしゃっておられたように絵や図を使います。十円玉をたくさん使うときもあります。ありふれた方法だと思いますが、端的に説明するのに非常に優れていると思います。
その上で、初めて書いてみせるコード例では1つのコード単位に複数の意味を持たせないよう、宣言文での初期化は行いません。
int *p = &n;
というコード例はどこにも間違いはないのですが、初心者にはどうみてもわかりにくいと思うんです。
みなさんは「*pはint型なのになぜ&nを代入できるのか」とか大見得を切って質問されたりしないんでしょうか。
これは「int *」型の変数pに&nを代入してるんだよ。「*p = 5;」とは違うんだっていちいち説明しなきゃいけなくなっちゃうんですけど。
int *p;
p = &n;
*p = 5;
なら誤解の余地はないです。
Re:ポインタとアドレッシング (スコア:1)
ACさんの発言とかぶる所があるのは申し訳ないです。
それをポインタと呼ぶ現場があることは理解しますが、ビット位置まで特定できるポインタは標準C言語には用意されてません。言語拡張されてビット位置も指定できる処理系がものがあっても驚きませんが、niqueさんの使っている処理系はそういう拡張がされているんでしょうか。あ~でも、gccとかでそんな拡張がされていてもおかしくないかも。そんなこと使えると思わないから使わないから気がつかないという。(笑)
# まあ使えると知っていても積極的に使おうと思わないですが。
vyama 「バグ取れワンワン」
Re: (スコア:0)
いえいえ、横レスですいませんですが。
繰り返しますがポインタはアドレスそのものです。
>一方、ポインタの指す場所はCPUが扱える最小のメモリ単位以下になる場合があります。
それは何かの誤解では?
1、ビットフィールドを指し示すポインタはない。
2、shortへのポインタであってもポインタの単位(アドレス)はバイト。
→ p++; の実際の動作は sizeof(short) を加算。printfで++前後のポインタ値を確認してみて。
ポインタの最も純粋な姿は、型を持たない(void*)です。
型を持つポイ