2

少し問題がありました。ベクトルの長さを計算できますが、ベクトルが同じ関数で定義されている場合に限られます。ベクトルを別の関数に渡そうとすると、間違った出力が返され、その理由がわかりません。

#include <stdio.h>

int len(int vec[]);

main()
{
    int a[6];

    printf("%d\n", sizeof(a)/sizeof(int));
    printf("%d\n", len(a));

    return 0;
}

len(int vec[])
{
    return sizeof(vec)/sizeof(int);
}    

出力は次のとおりです。

6
1

なぜ機能len()が動作しないのですか?1 ではなく 6 を返す必要があります。

4

3 に答える 3

7

これは、配列が関数に渡されると、最初の要素へのポインターに分解されるためです。

配列に関連付けられた長さの実行時ストレージがないため、これは機能しません。基本的に、関数の引数の場合、 などの型int a[]は と同等int *aです。つまり、単なるポインターです。

配列を関数に渡す必要がある場合は、常に長さを渡すのが最善であり、あなたのような関数を持つことはできませんlen()。例外はもちろん、文字列がターミネータ文字で行うように、指定されたデータに長さを自分で格納する場合です。

文体上のポイントとして、このコードは次のmain()とおりです。

printf("%d\n", sizeof(a)/sizeof(int));

私の意見では、次のように書く方が良いでしょう:

printf("%zu\n", sizeof a / sizeof *a);

次の注目すべき変更があります。

  • sizeofhas typeの結果はsize_t、 ではありませんint。format specifier によって正しく出力されます%zu
  • sizeofは関数ではないため、ほとんどの場合、括弧は必要ありません。
  • 変数に関連付けられているかどうかに関係なく型名を繰り返すよりも、変数への参照を優先します。「指し示すsizeof *a値のサイズ」を意味します。a
  • また、C の演算子の優先順位規則によれば、 は よりも厳密にsizeofバインド/されるため、式は実際には を意味することに注意してください(sizeof a) / (sizeof *a)。これは望ましい結果です。
于 2013-02-01T10:27:56.090 に答える
2

len関数は、指定されていないサイズの配列を引数として取ります。この場合、それは単なるポインター型 (あなたの場合はポインター) として扱われますint。特定のプラットフォームでは、ポインターのサイズは のサイズと同じで、int1sizeof(vec)/sizeof(int)です。

配列引数の長さを明示的に指定すると、サイズ計算は期待どおりに動作しますが、関数は正確にその長さの配列引数しか取りません。

参照:関数の引数としての C++ 配列

于 2013-02-01T10:28:29.900 に答える
1

なぜならint len(int vec[])、実際にはint len(int *vec). len変数の内部はvecポインタと見なされるsizeof vecため、アドレスを保存するために必要なバイト数が返されます。

sizeofは関数ではなく演算子であることに注意してください。つまり、 によって返される値sizeofはコンパイル時に計算されます。

于 2013-02-01T10:32:59.863 に答える