Posted at

「要素数 4 の配列を渡してください」ではなく「要素数 4 の配列を渡さなければならない」にする

More than 5 years have passed since last update.

例えば、何も考えずに配列を引数で受け取る関数を考えるとします。

すると、以下のようになるかと思います。


test.cpp

#include <iostream>


void Func(const short array[4])
{
using namespace std;

for (int i = 0; i < 4; ++i) {
cout << array[i] << endl;
}
}

int main()
{
short array[4] = {
0, 1, 2, 3,
};

Func(array);
return 0;
}


ぱっと見、なんの問題もないように見えますが、実はこれ、 配列ではなく単なるポインタ扱い になっています。

どういうこっちゃ?どう見ても配列でしょ?と思うかもしれませんが、

以下のコードと実行結果を見れば一目瞭然です。


test2.cpp

#include <iostream>


void Func(const short array[4])
{
using namespace std;
cout << sizeof(array) << endl;
}

int main()
{
using namespace std;

short array[4] = {};
cout << sizeof(array) << endl;

Func(array);
return 0;
}



output

8

4

関数外で sizeof すると、配列のサイズである 8 が出力されています。

が、関数内で sizeof するとあら不思議。出力されているのは 4 です。

この 4 はなんの 4 なのか?と言うと、これこそが short * のサイズである 4 となるわけです。

よって

void Func(const short array[4])

void Func(const short * array)

と同義というわけです。

まぁ、これでも 「short 型の要素数 4 の配列を渡してください」 という意図を伝えることはできますが、

残念ながら 「short 型の要素数 4 の配列を渡さなければならない」 ことにはできません。

あくまで short * なので、short * であれば、要素数が 10 でも 100 でも、

更には new したポインタ でさえ渡すことができちゃうわけです。




これをなんとか「short 型の要素数 4 の配列を渡さなければならない」ことにできないか?




これを実現できるのが 「配列の参照」 です。

百聞は一見にしかず。というわけで、コードと実行結果です。


test3.cpp

#include <iostream>


void Func(short (&array)[4])
{
using namespace std;
cout << sizeof(array) << endl;
}
int main()
{
using namespace std;

short array[4] = {};
cout << sizeof(array) << endl;

Func(array);
return 0;
}



output

8

8

(&array)[4] が「配列の参照」となります。

() 重要です。ないとコンパイルエラーで怒られます。

実行結果を見ると、関数内、関数外の両方で 8 が出力されてますね。

8 が出力されているということは、「short 型の要素数 4 の配列」として認識されているということです。

という訳で、これで無事に「short 型の要素数 4 の配列を渡さなければならない」を実現することが出来ました。

ちなみに、きちんと配列として認識されていますので、

for (int i = 0; i < SIZEOF_ARRAY(array); ++i) {

cout << array[i] << endl;
}

こんなこともできます。