次の関数でがn
等しくないのはなぜですか?8
void foo(char cvalue[8])
{
int n = sizeof (cvalue);
}
しかし、このバージョンの関数では次のようになりますn
。8
void bar()
{
char cvalue[8];
int n = sizeof (cvalue);
}
Cでは配列全体を関数パラメーターとして渡すことはできないためです。実際には、配列へのポインターを渡しています。括弧はシンタックスシュガーです。この関数は任意の文字ポインターを渡すことができるため、ポイントしている配列のサイズが8であるという保証はありません。
// These all do the same thing
void foo(char cvalue[8])
void foo(char cvalue[])
void foo(char *cvalue)
C および C++ 配列はファースト クラス オブジェクトではありません。配列を関数に渡すことはできません。配列は常にポインターに減衰します。
ただし、ポインターと参照を配列に渡すことはできます。これにより、配列の境界が減衰するのを防ぎます。したがって、これは合法です:
template<typename T, size_t N>
void foo(const T(&arr)[N])
{
int n = sizeof(arr);
}
最初の例では、渡されたパラメーターとしてのcvalueは、実際には文字配列への単なるポインターでありsizeof()
、それを取得すると、ポインターのサイズを取得します。ローカル変数として宣言した2番目のケースでは、配列全体のサイズを取得します。
32ビットシステムではパラメータのサイズは4になり、-m64でコンパイルされた64ビットシステムでは8になります。これは、配列が関数内のポインタとして渡されるためです。ポインタは単なるメモリアドレスです。