0

私は K&R の TCPL を読んでいます。

#include <stdio.h>
int sum(int a[])
{
    int t = 0;
    int length = sizeof(a) / sizeof(a[0]) ;
//  printf("%d\n",length);
    for(int i = 0; i != length; ++i)
    {
        t += a[i];
    }
    return t;
}
int main()
{
    int b[5] = {1, 2, 3, 4, 5};
    printf("%d\n",sum(b));
    return 0;
}

出力の答えは 1 NOT 15 です。次にprintf("%d\n",length);、出力の長さを追加してこのコードをデバッグします。1 NOT 5 です。TCPL は、配列名が引数として使用されると配列名がポインターに変換されることを伝えますが、出力の答えは間違っているので、私は不思議に思う:

  1. 引数として配列名を使用して関数を呼び出すとどうなりますか?
  2. で使用される配列a[]パラメーターにsum(int a[])ストレージがあるかどうか。
  3. 配列を呼び出すときに 2 つのスタイルが表示されます:fun(int a[]); fun(b)fun(int *a);fun(b),違いは何ですか?

ありがとうございます:-)

4

5 に答える 5

3

関数を呼び出して配列全体を渡すことはできません。配列名を関数の引数として使用すると、その最初の要素へのポインターとして (「減衰」) 暗黙的に書き換えられます。書くことと同等です。

 int sum(int *a) { ... }

したがって、関数内ではsizeof array、 は配列のサイズではなく、最初の要素へのポインターのサイズのみを示します。

では、配列に含まれる要素の数をどのように知るのでしょうか? この数値を明示的に関数に渡す必要があります (または、要素の数を指定してマクロを定義し、必要に応じて使用します)。

于 2013-03-19T08:01:17.890 に答える
1

sizeof次のように宣言された配列の呼び出し

 int a[5];

現在考えている配列のサイズを返します(つまり、配列のバイト単位のフルサイズ-この場合、私のマシンでは20バイトです)。このような配列を関数に渡すと、配列はその最初の要素へのポインターに減衰します。したがってsizeof、関数の引数を呼び出すと、実際にはポインター型で呼び出しています。関数がint *引数を取るように宣言した場合、呼び出す変数の型が明示的であるため、エラーはより明白になりますsizeof

于 2013-03-19T08:04:09.990 に答える
1

3 番目の質問は問題の核心になります。コンパイラに関する限り、これら 2 つに違いはありません。引数の受け渡し方法はすべて同じです。

したがって、2 番目の質問への回答として、aパラメーターには基になる配列用のストレージがなく、その配列のメンバーもコピーされません。割り当てられる唯一のストレージはint *ポインタ用であり、そのポインタは に格納されaます。(それはあなたの最初の質問にもいくらか答えます。)

したがって、あなたの関数では:

int length = sizeof(a) / sizeof(a[0]) ;

と同等です

int length = sizeof(int *) / sizeof(int);

ポインターと int が同じサイズのシステムでは 1 を返します。これを 64 ビット Linux で実行すると、ポインタが 64 ビットで int が 32 ビットであるため、代わりに 2 が返されます。

于 2013-03-19T08:05:16.120 に答える
0

あなたの呼び出しに問題はなく、 と の間fun(int a[])に違いはありませんfun(int *a)(読者には、ポインタではなく配列を期待していることがより明白になることを期待してください)。ボットの引数は、int へのポインターです。

ここでの問題は、配列の長さを決定する方法です。角かっこが空であるため、コンパイラが背後の配列の長さを知る方法はありませんa。たとえば、配列の長さを 2 番目の引数として指定できます。注: 関数を呼び出すとsizeof(b)、コンパイラがその長さを認識しているため、 は正しい長さを提供します。

于 2013-03-19T08:06:51.530 に答える
-1

このsizeof()演算子は、動的に割り当てられた配列の長さを取得するために使用できません。

ここでは、使用例を見つけることができますsizeof()

あなたがやろうとすると、sizeof(array_ptr)実際にはポインターのサイズが得られます

したがって、配列の長さを関数のパラメーターとして渡す必要があります

于 2013-03-19T08:30:39.010 に答える