• ベストアンサー

配列アドレスの減算

以下のようなプログラムがあったときに・・・ int vc[5]; printf("&vc[0] = %p\n", &vc[0] ); printf("&vc[1] = %p\n", &vc[1] ); printf("&vc[2] = %p\n", &vc[2] ); printf("&vc[2]-&vc[0] = %p\n", &vc[2]-&vc[0] ); 最後のprintfの結果が2と出ます。 &が付くとアドレスを表示すると思うのですが、アドレス同士の引算だと答えは2にはなりませんよね? これは要素の離れている差を表していると思うのですが、なぜアドレスの減算にならずにこのような結果になるのでしょうか? またアドレスの差を求める時はどうすればよいのでしょうか? よろしくお願いします。

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

  • ベストアンサー
  • ham_kamo
  • ベストアンサー率55% (659/1197)
回答No.2

ポインタの演算では、そのポインタの型が加減の単位となります。 下記URLの解説を参照してください。特に「21-7 ポインタを演算する」の Console.WriteLine( p2-p1 ); ではまさしく同じことをやっています。 http://www.atmarkit.co.jp/fdotnet/csharp_abc2/csabc2_021/cs2_021_03.html なお、アドレスの差を求めるには、 (&vc[2]-&vc[0])*sizeof(int) で求められるかもしれませんが、処理系に依存します。また、intでなく構造体のポインタの場合、うまくいかない可能性が高いです。詳しくは「アラインメント」で検索してみてください。

goo-ts
質問者

お礼

サイトのご紹介ありがとうございました。 理解できましたー!

その他の回答 (1)

  • Werner
  • ベストアンサー率53% (395/735)
回答No.1

> これは要素の離れている差を表していると思うのですが、なぜアドレスの減算にならずにこのような結果になるのでしょうか? それはアドレスの減算ではなくポインタの減算だからです。 ポインタは単なるアドレスではなく、 int型へのポインタというように型情報も含んでいて、 ポインタ演算は指す型のサイズを考慮して行われます。 (そうでないと、いろいろなところで不便です。) > またアドレスの差を求める時はどうすればよいのでしょうか? char *型にキャストするとか、sizeof(int)をかけるとか。

goo-ts
質問者

お礼

配列といっても結局はポインタとして考えないといけないんですね。なるほど、分りました。ありがとうございました。

関連するQ&A