void pass_arr(int arr[]);
void pass_arr_test()
{
int arr[5] = {1,2,3,4,5};
printf( "arr = %p\n"
"&arr = %p\n\n", arr, &arr);
pass_arr(arr);
}
void pass_arr(int arr[])
{
printf( "passed arr = %p\n"
"passed &arr = %p\n\n", arr, &arr);
}
输出:
arr = 0x28ccd0
& arr = 0x28ccd0
通过arr = 0x28ccd0
通过& arr = 0x28ccc0
有人可以解释为什么arr的值和地址在创建arr的块中进行评估时指向同一个地址,但是当将值和地址点传递给两个不同的地址时?
答案 0 :(得分:3)
那是因为函数 arr
实际上是指针,而不是数组。获取指针的地址不会产生相同的地址,就像它对数组所做的那样。
答案 1 :(得分:2)
除非它是sizeof
,_Alignof
或一元&
运算符的操作数,或者是用于在声明中初始化另一个数组的字符串文字, >“{元素数组T
”类型的>表达式将被转换(“衰减”)到类型“指向T
的指针”,表达式的值将是地址数组 1 的第一个元素。
致电时
`pass_arr(arr)`;
表达式arr
从“int
的5元素数组”转换为“指向int
的指针”或int *
。
注意,数组的第一个元素的地址是数组本身的地址;这就是为什么在打印arr
和&arr
int pass_arr_test
的结果时获得相同值的原因,但请记住类型是不同的;表达式arr
已转换为int *
类型,但&arr
的类型为int (*)[5]
;这对于指针算术等问题很重要。
其次,在函数原型的上下文中,T a[]
和T a[N]
形式的声明被解释为T *a
;实际上a
被声明为指针而不是数组。 2
要记住的重要一点是数组不是指针。相反,在大多数情况下,数组表达式根据需要转换指向指针。
答案 2 :(得分:0)
这是由于pass by value
语义,其中pass_arr方法中的arr是堆栈上的本地指针变量,其值是从pass_arr_test方法传递的arr
的位置。因此,pass_arr和pass_arr_test中的arr
变量指向相同的位置,因此值相同。由于它们是两个不同的指针,因此它们的内存地址不同。在数组定义的情况下,arr只是数组开头的别名,因此它的位置和它的值是相同的。