71

次のプログラムを考えると、

#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
  1. 配列が最初の要素へのポインタとして渡されるのはなぜですか?
  2. それはCからの遺産ですか?
  3. 基準は何と言っていますか?
  4. C++ の厳密なタイプ セーフが削除されたのはなぜですか?
4

3 に答える 3

89

はい、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 を返す関数へのポインター」になるように調整されます。

構文を説明するには:

Google で「右左」ルールを確認してください。ここに 1 つの説明がありました。

この例では、おおよそ次のように適用されます。

void foo (char (&a)[100]);

識別子「a」から開始

「あ」は

右に移動 - を見つけた)ので、方向を逆にして を探し(ます。左に移動すると通過します&

「a」は参照です

その後、&開口部に到達した(ので、再び反転して右を見ます。私たちは今見ます[100]

'a' は 100 の配列への参照です

そして、到達するまで再び方向を反転しますchar:

「a」は 100 文字の配列への参照です

于 2009-08-25T13:22:38.113 に答える
16

はい。C および C++ では、配列を関数に渡すことはできません。仕方ないよ。

とにかく単純な配列をやっているのはなぜですか?boost/ std::tr1::array/std::arrayまたはを見たことがありますかstd::vector?

ただし、任意の長さの配列への参照を関数テンプレートに渡すことができることに注意してください。私の頭の上から:

template< std::size_t N >
void f(char (&arr)[N])
{
  std::cout << sizeof(arr) << '\n';
}
于 2009-08-25T13:22:13.947 に答える
1

C/C++ の用語には、静的配列と関数ポインターに使用される壮大な言葉があります -減衰。次のコードを検討してください。

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
于 2011-12-21T16:53:07.673 に答える