4

重複の可能性:
CでのSizeofの動作

次のCコードがなぜそのように動作するのか誰かが説明できますか?

#include <stdio.h>

int sizeof_func(int data[]) {
    return sizeof(data);
}

int main(int argc, char *argv[]) {
    int test_array[] = { 1, 2, 3, 4 };
    int array_size = sizeof(test_array);
    printf("size of test_array : %d.\n", array_size);
    int func_array_size = sizeof_func(test_array);
    printf("size of test_array from function : %d.\n",
        func_array_size);
    if (array_size == func_array_size) {
        printf("sizes match.\n");
    } else {
        printf("sizes don't match.\n");
    }
    return 0;
}

出力は次のようになると予想しました。

size of test_array : 16.
size of test_array from function : 16.
sizes match.

しかし、代わりに私は得ました:

size of test_array : 16.
size of test_array from function : 4.
sizes don't match.
4

5 に答える 5

11

配列を関数の引数として渡すと、最初の要素へのポインターに減衰します。
sizeofin関数は、配列ではなくポインタのサイズを返します。
一方、配列sizeofmain()戻り値のサイズ。当然、両方が同じではありません。

関数内の配列のサイズを知りたい場合は、それを関数への個別の引数として渡す必要があります。

int sizeof_func(int data[], size_t arrSize);
                            ^^^^^^^^^^^^
于 2012-06-15T06:22:32.750 に答える
4

あなたの関数は以下と同等です:

int sizeof_func(int *data) {
    return sizeof(data);
}

関数に渡された配列のサイズについて関数が知る方法はありません。実際に渡されるのは、配列の最初の要素へのポインターだけだからです。あなたは32ビットシステムを使用しているので、sizeof(int *)は4です。

実際、sizeof(...)はコンパイル時に評価される定数であるため、作業する方法はありませんsizeof_func。代わりに、Cでよく行われるのは、次のように、ポインターを使用して整数を渡すことです。

int function_that_operates_on_array(int *data, int size)
{
    // do stuff with data[0] through data[size-1]
}
于 2012-06-15T06:26:14.067 に答える
3
   int test_array[] = { 1, 2, 3, 4 };
   int array_size = sizeof(test_array);
   printf("size of test_array : %d.\n", array_size);

ここで、コンパイラtest_arrayは配列と見なします(コンパイル時に配列の実際のサイズを認識します)。そのため、の実際のサイズを取得しますtest_array

   int func_array_size = sizeof_func(test_array);
   printf("size of test_array from function : %d.\n",
   func_array_size);

ただし、配列を関数に渡すと、コンパイラはそれを配列の最初の要素へのポインタと見なします(コンパイル時に、関数は配列のサイズを認識しません。これは、次の任意の配列で関数を呼び出すことができるためです。以前に宣言した)そのため、ポインタのサイズを取得しています。

于 2012-06-15T06:27:24.420 に答える
1

関数の定義は、

int sizeof_func(int data [])

{{

sizeof(data);を返します。

}

関数呼び出しの引数として配列の最初の要素へのポインタを渡しているため、これはあなたの場合には正しくありません。例:int func_array_size = sizeof_func(test_array);

以下のように関数定義を変更します。

int sizeof_func(int * data、int arraysize)

{{

 return (sizeof(data) * arraysize); 

}

そして、関数呼び出しを次のように変更します。int func_array_size = sizeof_func(test_array、4);

これはうまくいくはずです。

于 2012-06-15T06:49:11.107 に答える
1

知っておく必要のあるC言語の問題が2つあります。

1)sizeof演算子の動作。静的サイズのアレイでのみ機能します。がある場合はsizeof(test_array)、実際の配列で機能します。

int test_array[]  = { 1, 2, 3, 4 }; 
int test_array[4] = { 1, 2, 3, 4 }; // completely equivalent
char test_array[] = "something";

ポインタを渡すと機能しません。そうした場合、ポインタのサイズを取得します。次の場合は機能せず、4を出力します(32ビットを想定)。

int*  pointer = test_array;
char* pointer = "something";
printf("%d", sizeof(pointer));

2)関数パラメータの動作。これらはCで奇妙な構文を持っています。配列のように見えると宣言できますが、そうではありません。

void func (int* x);    // x is a pointer
void func (int x[]);   // x is a pointer
void func (int x[10]); // x is a pointer

上記の3つは同等であり、後者の2つは、プログラマーの意図を説明するための単なる「シンタティックシュガー」です。

これらすべての場合において、sizeof(x)を呼び出そうとすると、ポインターのサイズが得られます。

于 2012-06-15T07:01:34.063 に答える