mov.l A,a1 ; ok. 配列Aへの参照をa1に入れている。
mov.b @a1,d1 ; 曖昧。a1は配列への参照であってA[0]への参照ではない。
mov.b @a1+1,d1 ; ok. A[1]をd1に入れている。
inc a1 ; NG. a1がAの先頭を指さなくなる。プログラマの意図に反している。
mov.l A,a2 ; ok. A[0]を指す反復子をa2に入れている。
mov.b @a2,d2 ; ok. *a2をd2に入れている。
mov.b @a2+1,d2 ; ok. a2をランダムアクセス反復子として使っている。
inc a2 ; ok. a2をランダムアクセス反復子として使っている。
まぁ、驚いたのは (スコア:0)
指摘されても問題が何か理解出来ていない編集にはビックリだな
Re: (スコア:2, 興味深い)
自分でプログラミングすることなんか全く無いんでしょうね。
Re: (スコア:1, すばらしい洞察)
ポインタがいまいち理解できない人には朗報だ。
Re: (スコア:0, すばらしい洞察)
それで正しいと思います。
Cのポインタは、
- スカラ値への参照
- 配列への参照
- 動的オブジェクトの所有権管理
- 反復子
これら全然違う概念を一個で実現しようとする、そもそも無茶なキメラですよ。
私はC++使いなんですが、C++なら、状況によって参照やスマートポインタや反復子を使い分けるところです。
理解しようとするとかえって遠回りだと思います。
Re: (スコア:1, すばらしい洞察)
> - スカラ値への参照
> - 配列への参照
> - 反復子
すまん アセンブラだと、こういうコードかかない?
#つーか普通のレジスタの使い方だと思ったけど
#違うのかな?
> - 動的オブジェクトの所有権管理
これは わかんないけど
Re:まぁ、驚いたのは (スコア:0)
アドレスレジスタa0, a1, a2を、それぞれスカラへの参照、配列への参照、
反復子として使おうとしてると思ってくださいよ。
A: ; 配列
db 00h, 01h, 02h
S: ; スカラ
db 20h
main:
mov.l S,a0 ; ok. スカラ値Bへの参照をa0に入れている。
mov.b @a0,d0 ; ok. Bをd0に入れている。
mov.b @a0+1,d0 ; NG. Bは配列ではない。プログラマの意図に反している。
inc a0 ; NG. a0の指すところにデータは無い。プログラマの意図に反している。
mov.l A,a1 ; ok. 配列Aへの参照をa1に入れている。
mov.b @a1,d1 ; 曖昧。a1は配列への参照であってA[0]への参照ではない。
mov.b @a1+1,d1 ; ok. A[1]をd1に入れている。
inc a1 ; NG. a1がAの先頭を指さなくなる。プログラマの意図に反している。
mov.l A,a2 ; ok. A[0]を指す反復子をa2に入れている。
mov.b @a2,d2 ; ok. *a2をd2に入れている。
mov.b @a2+1,d2 ; ok. a2をランダムアクセス反復子として使っている。
inc a2 ; ok. a2をランダムアクセス反復子として使っている。
同じアドレスレジスタという方法で実装していますが、プログラマの意図としては
それぞれ性質が異なることがお分かりでしょうか?
本来別々のものなのですが、アドレスレジスタやポインタの使い方を体得してる人は、
無意識に使い分けていて、違いを感じなくなってるのじゃないでしょうか。
それにアセンブラじゃアドレスレジスタしか無いですからね。
逆に、これらの区別ありきのプログラマにとってはすごく違和感があるのです。
違うもんなんだから違う書き方させろ(そしてできないことはコンパイルエラーにしろ)
という。
Re:まぁ、驚いたのは (スコア:2, すばらしい洞察)
自分の場合、C/C++ではポインタはメモリのどこかを指しているものという認識しかないですし、配列はメモリ上に連続してとられたスカラ値の集まりという認識しかないです(*1)。
だからポインタを持ってきて「スカラへの参照」「配列への参照」「反復子」として捉えることは無いですね。敢えて表現するならばポインタというものは一種類で「スカラ」「配列の先頭」「配列中のどこか」「ふめいなところ」を指していると捉えてる感覚でしょうか。
*1)なので、必ずしもメモリ上で連続していないようなコレクションの実装を指して「配列(もしくは Array)」と呼ぶのは違和感がある。