次のプログラムを考えると、
#include <iostream>
using namespace std;
void foo( char a[100] )
{
cout << "foo() " << sizeof( a ) << endl;
}
int main()
{
char bar[100] = { 0 };
cout << "main() " << sizeof( bar ) << endl;
foo( bar );
return 0;
}
出力
main() 100
foo() 4
はい、Cから継承されます。関数:
void foo ( char a[100] );
パラメーターがポインターになるように調整されるため、次のようになります。
void foo ( char * a );
配列タイプを保持したい場合は、配列への参照を渡す必要があります。
void foo ( char (&a)[100] );
C++ '03 8.3.5/3:
...関数のタイプは、次のルールを使用して決定されます。各パラメーターのタイプは、独自のdecl-specifier-seqおよび宣言子から決定されます。各パラメーターのタイプを決定した後、「Tの配列」または「Tを返す関数」タイプのパラメーターは、それぞれ「Tへのポインター」または「Tを返す関数へのポインター」に調整されます。
構文を説明するには:
グーグルで「左右」ルールを確認してください。私はそれの説明を見つけました ここ 。
この例には、およそ次のように適用されます。
void foo (char (&a)[100]);
識別子「a」から開始
「a」は
右に移動-)
そのため、(
。左に移動すると、&
「a」は参照です
後に &
開口部に到達(
そのため、再び逆向きになり、正しく見えるようにします。 [100]
'a'は100の配列への参照です
そして、char
に達するまで再び方向を逆にします。
'a'は100文字の配列への参照です
はい。 CおよびC++では、配列を関数に渡すことはできません。仕方ないよ。
とにかくプレーン配列をしているのはなぜですか? boost
/std::tr1::array
/std::array
またはstd::vector
を見ましたか?
ただし、任意の長さの配列への参照を関数templateに渡すことができます。私の頭の上から:
template< std::size_t N >
void f(char (&arr)[N])
{
std::cout << sizeof(arr) << '\n';
}
C/C++の用語には、静的配列と関数ポインターに使用される素晴らしいWordがあります-decay。次のコードを検討してください。
int intArray[] = {1, 3, 5, 7, 11}; // static array of 5 ints
//...
void f(int a[]) {
// ...
}
// ...
f(intArray); // only pointer to the first array element is passed
int length = sizeof intArray/sizeof(int); // calculate intArray elements quantity (equals 5)
int ptrToIntSize = sizeof(*intArray); // calculate int * size on your system