• ベストアンサー

ポインタと出力について

現在C言語を勉強している者ですが、参考書をもとに自分でソースコードを書いて少し疑問に思った所がありました。以下がそのソースコードです。 #include <stdio.h> int main(void) { int dt = 0x41424344; int *ip; char *cp; ip = &dt; cp = (char *)ip; printf("%x\n", *ip); printf("%x\n", *cp); printf("%x\n", *cp++); printf("%x\n", *cp++); printf("%x\n", *cp++); return 0; } 出力結果は 41424344 44 44 43 42 となります。 私の予想していた結果は 41424344 44 43 42 41 でしたが、結果はなぜか44が二回出力されています。 2番目のprintf("%x\n", *cp); と 3番目のprintf("%x\n", *cp++);は明らかに3番目のprintfが *cp++ で番地が1つ進んでいると思うのですが結果を見る限りでは同じ数字44が出力されています。なぜこうなってしまうのでしょうか? 説明不足でしたらまた追加しますのでどうかよろしくおねがいします。  

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

>なぜこうなってしまうのでしょうか? 計算した「結果」は同じでも、「どのタイミングで」計算するかが違う為。 ++を後ろにつけた場合、print()文でcpの値を表示した後にcpのアドレスを加算している。 retur0の前に以下を追加して実行してみてください。 -------------------- ip = &dt; cp = (char *)ip; printf("%x\n", *ip); printf("%x\n", *cp); printf("%x\n", *(++cp)); printf("%x\n", *(++cp)); printf("%x\n", *(++cp)); --------------------

shomarket
質問者

お礼

ありがとうございます。 ip = &dt; cp = (char *)ip; printf("%x\n", *ip); printf("%x\n", *cp); printf("%x\n", *(++cp)); printf("%x\n", *(++cp)); printf("%x\n", *(++cp)); をreturn 0 の前に追加してわかりました。 つまり 最初の *cp++ は番地を +1 する前に出力していたのですね。わかりました。本当にありがとうございました。

その他の回答 (4)

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.5

>パソコンの処理系がリトルエイディアンで処理している プロセッサがリトルエンディアン(little endian)だからです。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

まず「エンディアン」については, 「異なる単位でアクセスするときには必ず付いて回る」と思ってください. 今の場合は int (4バイトか?) を char (1バイト) でアクセスしているので出てきていますし, 逆に char (や short) の配列を黒魔術的に int としてアクセスしようとしても出てくる可能性があります. 次にインクリメント (やデクリメント) の位置と得られる結果との関係ですが, こちらは #1 のように「++cp と cp++ の違い」, 特に「得られる結果の違い」を意識してください (優先順位も違うけどこれが影響することはないといっていいはず). ++cp は cp+1 を, cp++ は cp を与えます. cp の値が増えるのはこの計算の副作用であり, 主たる結果では (本来) ありません. ちなみに重箱の隅を突っつくと「*cp++ は番地を +1 する前に出力していた」というのは間違いです. 関数呼び出しの前後に副作用完了点が存在するため, 「cp が 1 増える」という副作用は「printf を呼び出す前」に完了します. つまり, printf の本体を実行するときには (アクセスできないので無意味だけど) cp の値は既に 1 だけ増えているはずです.

shomarket
質問者

お礼

そんな仕組みはじめて知りました。ありがとうございます。C言語の奥の深さが少しわかった気がします。

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.3

>私の予想していた結果は >41424344 >44 >43 >42 >41 最後の4行が 41 42 43 44 とならない理由は理解されているのですね?

shomarket
質問者

補足

おそらく自分のパソコンの処理系がリトルエイディアンで処理しているからだと思います。よく覚えてないのですがリトルエイディアンは16進数の出力のときにのみに働く機能なのですか?

  • hashioogi
  • ベストアンサー率25% (102/404)
回答No.1

++cpとcp++の違いがわかりますか ?