- ベストアンサー
ポインタについて
ポインタについて質問です。 int *pa; pa = 0003; *pa = 3; とした場合、 以下のケースはそれぞれ、どう違うのでしょうか? *(pa++) = 10; *(pa + 1) = 10; *pa++ = 10; (*pa)++ = 10; *pa + 1 = 10; (*pa)++ = 10; よろしくお願いします。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
No.1さんの回答には誤りが含まれています。 char* pa; ならば正解ですが・・・ intのサイズは処理系次第です。 だから、 intのサイズが分からないと答えようがない ということなのですが・・・ 一般的な32ビットを仮定します。 intが64ビットの処理系もあります。 その場合は、連想で、ご自分で考えてください。 (1)*(pa++) = 10; pa が評価される pa = 0003 paがインクリメントされる 単純に1加算されるわけではありません。 型のサイズ分移動します。 intが32ビット(=4バイト)の場合 4バイト単位での移動となります。 従って移動後のpa(アドレスは) 3 + 4 = 7により 0007となります。 paの位置に10を書き込みます。 pa = 7 *pa = 10 です。 (2)*(pa + 1) = 10 pa が評価される pa = 0003 paの1つ隣のアドレスを算出する 1加算したアドレスではありません (1)を参照下さい。 4バイト先を参照します 従って 0007位置に10が書き込まれます。 ちなみに、この表記は pa[1] = 10 と全く同じです。 こちらの方が分かりやすく、誤解も少ないので 私はこの表現を好んで使います。 (3)*pa++ = 10; http://c-production.com/special/04092101.html によると *(間接演算子)と++は同一優先順位です。 左から順に実行されます つまり *(pa)++= 10 と同じことです paの現在値(0003)に10を書き込み paをインクリメントします。 pa は7になります。 (4)(*pa)++ = 10; (3)と全く同じことの別表現です。 残りは文法違反であり得ません。
その他の回答 (6)
- Tacosan
- ベストアンサー率23% (3656/15482)
手元のシステムでは, 「0003 番地に書き込もうとした瞬間」にこけました>#5. まあ, 「特殊」と言えば「特殊」なシステムなのかもしれんが. ということで, 「システムがわからんとなんとも答えようがない」という結論で終わってしまう.
- jacta
- ベストアンサー率26% (845/3158)
こんなふうに、ポインタに直接代入するようなことをやっている場合、組込み開発にかかわっている可能性が高いと思います。 それも8ビットから16ビット程度のローエンド機種で、OSがあるかないかもわからないような...
- BLK314
- ベストアンサー率55% (84/152)
勿論、特殊を言いだすと切りがありません。 極端な話、0003にアクセスした瞬間にアクセス違反が発生する システムだって存在する訳です。 その場合、回答は 全て実行不可能となります。 0003はOkだが0004から0FFFはアクセス禁止のシステムだって あり得ます。 でも、そんなこと言ってたら切りがないです。 OSは無論のこと メモリマップをきちんと提示せよとかなります。 それは、質問者の意図に沿わないと考えます。 ですから、わざわざ「一般的な32ビット系」と但し書きを入れているのですよ。 論文やなんかであれば、アライメントがどうとか厳密に指定しなければなりません。 しかし、質問者様の「スキル」に想像を馳せてください。 「アライメント」や「メモリマップ」を気に掛ける人が こんな質問すると思いますか? 一般に最も普及していると思われる32ビット系 x86辺りを例として想定しておけば、 まず、間違いないでしょう。 例外については、もっとスキルが上がって メモリを自由自在にアクセスできる自信が付いたときに 改めて、アライメントとか学べばいいはずです。 小学校で漢数字を習ったときのことを思い出して下さい。 「一、二、三」と習ったはずです。 勿論、これには例外があり、 お金なんかを表す時には、簡単に書き換えられないよう 「壱、弐、参」 でなければなりません。 しかし、初めて漢数字を習う小学生に 例外まで叩き込むのは酷だと思いませんか? 漢字に慣れてから 「実はこういう場合は例外的に・・・・」 と教えられたと思います。 それと同じで、 スキルが低い人に対し、 「例外がある」 と教え込むのは酷だと考えます。 まず、一般的な環境で正しくポインタを理解することが先決です!
- jacta
- ベストアンサー率26% (845/3158)
さらに細かい話をすると、int型へのポインタとchar型(またはvoid型)へのポインタの内部表現が同じであるかどうかも処理系によります。 int*はsizeof(int)を単位としたアドレスで、char*はsizeof(char)を単位とするアドレスでもかまわないのです。
- Tacosan
- ベストアンサー率23% (3656/15482)
もっと細かいことをいうと「intが32ビット(=4バイト)」とも断定できないんですけどね>#2. 「1バイト」は「char 1個分」だけど, 「char 1個分が何ビットか」も処理系に依存します. つまり「1バイト = 32ビット」という処理系があってもいいし, そのような処理系では #1 のようにふるまうことも考えられます. あと, char が 8ビットかつ int が 32ビットの環境でも, int *pa; pa = 0003; *pa = 3; が正常に動作するかどうかは分かりません (アラインメント違反になったりする可能性だってある). ということで, ここに挙がっているプログラム断片がすべて処理系依存であり, 処理系を特定しないと「こうなる」とは言えないはずです.
- magicalpass
- ベストアンサー率58% (378/648)
(1) *(pa++) = 10; 0003 <- 10 pa <- 0004 (2) *(pa + 1) = 10; 0004 <- 10 pa == 0003 (3) *pa++ = 10; 0003 <- 10 pa <- 0004 (4) (*pa)++ = 10; Syntax Error (5) *pa + 1 = 10; Syntax Error (6) (*pa)++ = 10; Syntax Error