sizeof なんぞにこんなに章を割いていいものか迷いましたが、結局2章に分けて話しています。今回はその第2回目です。
では、今回の要点です。
では、いってみましょう。
前回、sizeof を使えば配列のサイズが分かると言いました。でも、ああそうなんだと思って以下のようなプログラムを組むと、変な結果になってしまいます。
プログラム | 実行結果 |
---|---|
// Sizeof2.cpp #include <iostream.h> void DispSize(const char* array) { cout << "この配列のサイズは " << sizeof array << " バイトです。" << endl; } int main() { char data1[100]; char data2[200]; DispSize(data1); DispSize(data2); return 0; } |
この配列のサイズは 4 バイトです。 この配列のサイズは 4 バイトです。 |
なぜこんな結果になるのでしょうか?
答は簡単です。DispSize の引数 array の型は const char* だからです。array はポインタなので、sizeof をとると答は4になります。
では、DispSize 内で配列のサイズを取得する方法はないのでしょうか? 実は、ありません。なので、配列のサイズを使いたければ、サイズは引数に渡さなければいけないのです。
ああそうなんだ、と次のようなプログラムを組むと、また変なことになってしまいます。これは、フィボナッチ数列(前2つの要素の和をその要素とする数列)を作って、それを出力するプログラムなのですが...。
プログラム |
---|
// Sizeof3.cpp #include <iostream.h> void StoreFibo(int* array, int nSize) { int i; if(nSize < 0) return; array[0] = 1; if(nSize == 1) return; array[1] = 1; for(i = 2; i < nSize; i++) array[i] = array[i - 1] + array[i - 2]; } void DispFibo(const int* array, int nSize) { int i; for(i = 0; i < nSize; i++) cout << array[i] << ' '; cout << endl; } int main() { int nFibo[10]; StoreFibo(nFibo, sizeof nFibo); DispFibo(nFibo, sizeof nFibo); return 0; } |
実行結果がありませんね。なぜなら、このプログラムを実行すると大変なことになるからです。
sizeof は、ある変数のバイト単位でのサイズを取得するものです。なので、int 型の要素が10個の配列 nFibo の sizeof をとると、答は40になります。要素は40もないのに StoreFibo では40も書き込もうとしてしまいます。このため、異常な動作を起こし、最後には異常終了してしまいます。
ならどうすればいいのでしょうか? 答はやはり簡単です。要素のサイズで割ればいいのです。
sizeof nFibo / sizeof *nFibo
nFibo は int 型の配列です。なので、*nFibo の型は int になります。よって、sizeof *nFibo は4になります。で、結局この値は40÷4=10となり、無事要素数を取得できました。
この処理は、マクロにしておくと後々便利でしょう。(関数では無理です。関数を通すとサイズは取得できないのでしたね。)
#define ELEM(array) (sizeof (array) / sizeof *(array))
これを使って、上のプログラムを書き換えてみて下さい。これで、満足のいく動作を行ってくれるようになったでしょう。
これで sizeof については終わりです。では、今回の要点をおさらいしましょう。
これで sizeof については終わりです。次回はいよいよ構造体について話します。C++のクラスに繋がる重要なものですから、しっかり理解しましょう。では。
Last update was done on 2000.7.4
この講座の著作権はロベールが保有しています