C中的array_length

Sup*_*ing 10 c arrays

我写了一个像这样的array_length函数:

int array_length(int a[]){
    return sizeof(a)/sizeof(int);
}
Run Code Online (Sandbox Code Playgroud)

然而,当我这样做时它会返回2

unsigned int len = array_length(arr);
printf ("%i" , len);
Run Code Online (Sandbox Code Playgroud)

我在哪里

int arr[] = {3,4,5,6,1,7,2};
int * parr = arr;
Run Code Online (Sandbox Code Playgroud)

但是当我这么做的时候

int k = sizeof(arr)/sizeof(int);
printf("%i", k);
Run Code Online (Sandbox Code Playgroud)

在main函数中,它返回7.

编写array_length函数的正确方法是什么?如何使用它?

Ree*_*sey 16

计算数组长度(以C为单位)充其量是个问题.

上面代码的问题在于:

int array_length(int a[]){ 
    return sizeof(a)/sizeof(int); 
} 
Run Code Online (Sandbox Code Playgroud)

你真的只是传递一个指针为"A",所以sizeof(a)sizeof(int*).如果您使用的是64位系统,那么sizeof(a)/sizeof(int)在函数内部总是会得到2 ,因为指针将是64位.

您可以(可能)将此作为宏而不是函数执行,但这有它自己的问题...(它完全内联这一点,因此您获得与int k =...块相同的行为.)

  • @Lothar:我几十年前使用的旧Cray C编译器有64位整数... (2认同)

Dav*_*ley 12

你的功能不起作用.C数组和C指针是不同的类型,但如果你看它有趣,数组将退化为指针.

在这种情况下,您将数组作为参数传递,并且它在调用中变为指针,因此您正在测量sizeof(int *)/sizeof(int).

使这项工作的唯一方法是使用宏:

#define ARRAYSIZE(x) (sizeof(x)/sizeof(*x))
Run Code Online (Sandbox Code Playgroud)

并且只有x在该范围内声明为数组而不是指针时才会起作用.


Goz*_*Goz 9

使用宏...

#define SIZEOF_ARRAY( arr ) sizeof( arr ) / sizeof( arr[0] )
Run Code Online (Sandbox Code Playgroud)

它还有任何阵列数据类型的工作奖励:)

  • 与功能不同,它确实具有可能正常工作的优点. (5认同)
  • @David:这不是最重要的:有时可能正常工作的代码吗? (2认同)

Ash*_*unn 5

一般来说,测量数组大小是不可能的.在你的main函数中,编译器会为你在大括号之间编写的元素进行计数,所以你真的要声明int arr[7].这有你期望的尺寸.

但是,在您的函数中,int a[]等效于int *a- 指向整数的指针.知道它是一个数组,所以有更多的整数跟随,但你的array_length函数可以传递任何整数指针,所以它无法知道.

这是尽可能使用std::vector而不是原始数组的众多原因之一.


Alo*_*hal 5

你的问题的简单答案是:没有办法写这个array_length函数.您可能能够使用宏定义,但这取决于您将使用宏的上下文.

您在C中混淆了数组和指针时遇到了常见的错误.在C中,数组的名称在大多数情况下等同于指向其第一个元素的指针.您的array_length函数a在这样的上下文中接收数组.换句话说,不可能将数组作为 C中的数组传递.您的函数就好像它是这样定义的:

int array_length(int *a){
    return sizeof(a)/sizeof (int);
}
Run Code Online (Sandbox Code Playgroud)

其中,基本上除以大小int *的大小int.而且,通过以上描述,不可能在函数中知道C中的阵列的大小.

现在,如何在功能之外正确确定其大小?答案是sizeof运算符是数组名称不会减少为指向其第一个元素的指针的情况之一.我已经在这个答案中更精细地解释了这些差异.还要注意,尽管是外观,但是sizeof是一个操作符,而不是一个函数(正如我们刚刚学到的,它不能是一个函数,因为它将无法计算数组的大小).

最后,为了确定a任何类型的数组的大小T,我更喜欢:

size_t sz = sizeof a / sizeof a[0];
Run Code Online (Sandbox Code Playgroud)

以上是与类型无关的:a可以是上面的任何类型.实际上,您甚至可以更改类型,a而不需要更改上述内容.