数组的值和地址是相同的,除非传递给函数?

时间:2012-09-22 11:11:56

标签: c arrays pointers

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的块中进行评估时指向同一个地址,但是当将值和地址点传递给两个不同的地址时?

3 个答案:

答案 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

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

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

答案 2 :(得分:0)

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