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
この講座の著作権はロベールが保有しています