22

以下のプログラムでは、配列の長さはarメインでは正しいですが、私のコンピューターでは 2 (の単位)tempであるポインターの長さを示しています。arsizeof(int)

#include <stdio.h>

void temp(int ar[]) // this could also be declared as `int *ar`
{
    printf("%d\n", (int) sizeof(ar)/sizeof(int));
}

int main(void)
{
    int ar[]={1,2,3};
    printf("%d\n", (int) sizeof(ar)/sizeof(int));
    temp(ar);
    return 0;
}

配列の長さが関数で正しく読み取られるように、関数を定義する方法を知りたかったのです。

4

7 に答える 7

29

関数内の長さを決定する「組み込み」の方法はありません。ただし、 を渡すarrと、sizeof(arr)常にポインターのサイズが返されます。したがって、最良の方法は、要素の数を別の引数として渡すことです。あるいは、終了を示す0orのような特別な値を持つこともできます(文字列のように、単に です)。しかし、もちろん、「論理」配列のサイズは-1\0char []sizeof(arr)/sizeof(int) - 1

于 2013-07-11T09:53:11.977 に答える
12

関数を使用しないでください。これにはマクロを使用してください。

//Adapted from K&R, p.135 of edition 2.
#define arrayLength(array) (sizeof((array))/sizeof((array)[0]))

int main(void)
{
    int ar[]={1,2,3};
    printf("%d\n", arrayLength(ar));
    return 0;
}

temp他の人が言及した理由により、配列がパラメーターとして渡されるような関数内でこのマクロを使用することはできません。

1 つのデータ型を渡したい場合の代替手段は、配列と容量の両方を持つ型を定義することです。

typedef struct
{
  int *values;
  int capacity;
} intArray;

void temp(intArray array)
{
  printf("%d\n", array.capacity);
}

int main(void)
{
    int ar[]= {1, 2, 3};
    intArray arr;
    arr.values = ar;
    arr.capacity = arrayLength(ar);
    temp(arr);
    return 0;
}

これはセットアップに時間がかかりますが、多くの関数を自分で渡している場合に便利です。

于 2013-07-11T10:04:18.243 に答える
8

あなたが書くとき、配列ではなくポインタsize(ar)渡しています。

ポインターと int のサイズは 4 または 8 です - ABIに応じて(または、@H2CO3 が言及したように - まったく異なるもの)、sizeof(int *)/sizeof int(32 ビット マシンの場合は 4/4= 1、8/4= の場合は 4/4=1 になります)。 64 ビット マシンの場合は 2)、これは 1 または 2 (または..何か違うもの) です。

C では、関数に引数として配列を渡す場合、配列へのポインターを渡していることを思い出してください。
配列のサイズを渡したい場合は、別の引数として渡す必要があります。

于 2013-07-11T10:00:37.540 に答える
0

関数 ar の内部にはポインターがあるため、sizeof 演算子はポインターの長さを返します。それを計算する唯一の方法は、ar をグローバルにするか、その名前を変更することです。長さを決定する最も簡単な方法は、size(array_name)/(size_of(int) です。もう 1 つの方法は、この計算を関数に渡すことです。

于 2013-07-11T09:52:35.443 に答える