这个问题已经在这里有一个答案:
这是下面的代码来说明这个问题:
#include <stdio.h>
void func(int arr[]);
int main() {
int arr[10];
int n = *(&arr + 1) - arr;
printf("%d\n", n);
func(arr);
return 0;
}
void func(int arr[]) {
int n = *(&arr + 1) - arr;
printf("%d\n", n);
}
上面的代码的输出是:
10
268435906
尽管用于其定义void func(int arr[])
语法,功能func
接收指向该阵列的第一个元素。该定义是void func(int *arr)
清晰。
表达*(&arr+1)-arr
在编译时的计算结果为仅当arr
被定义为一个阵列的阵列的元件的数量。如果arr
是一个指针,它指针取消引用后内存和减去指针值,这是毫无意义的,在大多数情况下是未定义行为。
更常见的(并且更可读的)表达来获得元件的编号的数组是
n = sizeof(arr) / sizeof(*arr);
如果arr
是一个数组,通过在字节的元件的尺寸除以它的以字节为单位的大小产生元件的数目。在编译时,没有运行时开销的表达进行评估。如果arr
是一个指针,由类型的大小除以它的大小它所指向的定义,但没用,就像你的表达。
当一个函数声明数组参数,它不是在所有的数组,而不是它的一个指针。
声明
void funct(int arr[]);
实际上等于
void funct(int *arr);
这就是你看到的结果之间的差异。在main
功能&arr
是一个指针阵列,但在func
表达&arr
是指针的指针变量。这两个指针是非常不同的。
每当阵列作为函数参数传递,它们将衰变成在函数参数指针。
由于立即阵列衰变为指针,一个阵列被从未实际上传递给函数。可以假装一个函数接收的阵列作为参数,并通过声明对应的参数作为数组说明它:
空隙F(烧焦一个[]){...}
阵列arr
的名称被衰减到指针由编译器阵列的第一个元素。其结果,解除引用指针产生存储在阵列的第一位置的值。