2
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 的值和地址指向同一个地址,但是当将值和地址传递到两个不同的地址时?

4

3 回答 3

3

那是因为在函数arr中实际上是一个指针,而不是一个数组。获取指针的地址不会产生与数组相同的地址。

于 2012-09-22T11:13:29.183 回答
2

除非它是、 或 一元运算符的操作数sizeof,或者是用于在声明中初始化另一个数组的字符串文字,否则“N-element array of”类型的表达式将被转换(“decay”)为“指针”,表达式的值将是数组1的第一个元素的地址。 _Alignof&TT

你打电话时

`pass_arr(arr)`;

表达式arr从类型“5 元素数组int”转换为“指针int”,或int *.

注意数组第一个元素的地址就是数组本身的地址;这就是为什么在打印和int的结果时会得到相同的,但请记住类型是不同的;表达式转换为 type ,但有 type ;这对于指针算术之类的事情很重要。arr&arrpass_arr_testarrint *&arrint (*)[5]

其次,在函数原型的上下文中,形式的声明T a[]T a[N]被解释为T *aa实际上被声明为指针而不是数组。2

要记住的重要一点是数组不是指针。相反,在大多数情况下,数组表达式会根据需要转换为指针。


1 - N1570,6.3.2.1左值、数组和函数指示符,¶ 3
2 - N1570,6.7.6.3函数声明符(包括原型),¶ 7

于 2012-09-22T13:18:56.847 回答
0

这是由于pass by value语义,其中 pass_arr 方法中的 arr 是堆栈上的局部指针变量,其值是arr从 pass_arr_test 方法传递的位置。因此,arrpass_arr 和 pass_arr_test 中的变量都指向相同的位置,因此值是相同的。由于它们是两个不同的指针,所以它们的内存地址是不同的。在数组定义的情况下, arr 只是数组开头的别名,因此它的位置和值是相同的。

于 2012-09-22T11:19:46.363 回答