第39章 1+1=5??

 今回は1+1=5というような計算をします。アドレスの計算をすると、こんなことが起きてしまいます。


 では、今回の要点です。


 では、いってみましょう。


 アドレスは数値です。だったら計算もできるはずです。ただ、その結果はどういう値になるのでしょうか?

 今、仮に int array[4] という配列変数を考えてみます。例えば、そのアドレスが下のようになったとします。

名前 array[0] array[1] array[2] array[3]
アドレス 6618600 6618604 6618608 6618612

 このとき、&array[1] + 1 は何になるのでしょうか?

 きっと2つの案が出てくることでしょう。1つは、単に1を足して 6618585 になる、というもの。そしてもう1つは、&array[2] になる、というものです。

 では、プログラム作って調べてみましょう。

プログラム
// Address2.cpp
#include <iostream.h>

int main()
{
    int array[4];

    cout << "&array[1]     = " << (int)&array[1]       << endl
         << "&array[1] + 1 = " << (int)(&array[1] + 1) << endl
         << "&array[2]     = " << (int)&array[2]       << endl;

    return 0;
}
実行結果例
&array[1]     = 6618604
&array[1] + 1 = 6618608
&array[2]     = 6618608

 どうやら、&array[1] + 1 は &array[2] になるようです。

 この配列の型を char にしてみたらどうなるでしょうか? やはり &array[2] に等しくなります。double(大きさは8バイト)にしても、そうなります。(実際に確かめて下さい)

 このように、アドレスの足し算は型の大きさに左右されます。4バイトの大きさの型なら4ずつ、8バイトの大きさの型なら8ずつ足されます。

 何個か先の要素のアドレスを知りたいときに、いちいち型の大きさをかけて足さなくても、勝手にかけてくれるというわけです。

 当然と言えば当然なのですが、実際に数字を表示してみてみると少し違和感を感じると思います。でも、これに慣れて下さい。ついサイズをかけてしまうというバグに注意して下さい。


 このことは、ポインタを含む計算にも当てはまります。例えば、次のようなものです。

プログラム実行結果例
// Ptr4.cpp
#include <iostream.h>

int main()
{
    int  array[4];
    int* p = array;

    cout << (int)p<< endl;
    p +=2;
    cout << (int)p<< endl;

    return 0;
}
6618596
6618604

 p に足されたのは2ですが、実際には8が足されています。ポインタの型を把握していないと、ついこのことを忘れ、8を足そうとしてしまいます。そして、他のポインタに2を足したからといって、そのアドレスが8増えるとは限らないことも注意して下さい。


 さて、今までは足し算だけでした。足し算が出来るのですから、引き算ももちろん出来ます。ですが、かけ算はどうでしょうか?

 アドレスにかけ算をする必要があるのでしょうか? よほどのことがあっても、アドレスのかけ算をする必要は出てこないでしょう。

 実はやはりアドレスに乗除算は出来ないようになっています。どうしても乗除算がしたい人がいるなら、int でキャスト(21章参照)して下さい。


 今回はこれで終わりです。

 では、今回の要点をもう一度見てみましょう。


 次回はポインタの演算を使って文字列を操作してみます。では、また次回まで。さようなら。


第38章 参照のしくみ | 第40章 さらなる計算

Last update was done on 2002.2.28

この講座の著作権はロベールが保有しています