去引用如何作用于指向数组的指针?

时间:2019-05-23 17:45:37

标签: c pointers

在取消引用时指向元素数组的指针返回一个地址。 由于它保存着数组第一个元素的地址,因此对其取消引用应该返回一个值。

int arr[] = { 3, 5, 6, 7, 9 }; 
int *p = arr; 
int (*ptr)[5] = &arr;     
printf("p = %p, ptr = %p\n", p, ptr); 
printf("*p = %d, *ptr = %p\n", *p, *ptr);

输出:

p = 0x7fff6ea72d10,ptr = 0x7fff6ea72d10

* p = 3,* ptr = 0x7fff6ea72d10

为什么* ptr返回数组的基地址,它不应该返回该地址的值?

5 个答案:

答案 0 :(得分:8)

  

为什么* ptr返回数组的基地址,不是吗?   返回该地址的值?

(p3)除非它是sizeof运算符,_Alignof运算符或一元'&'运算符的操作数,或者是字符串常量用于初始化数组,将类型为“类型为数组” 的表达式转换为类型为“类型为指针” 的表达式,该表达式指向的初始元素数组对象,不是左值。 C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3)

int (*ptr)[5] = &arr;

ptrint [5]指针到数组。取消引用ptr时,会得到 {em> int[5]的数组。如何访问int[5]数组?

规则6.3.2.1提供了答案:

  

“类型为数组” 转换为类型为“要指向的指针” 的表达式,该表达式指向数组对象的初始元素...

现在,如果再次取消引用(例如**ptr),那么您将获得第一个元素的值。

答案 1 :(得分:3)

问题是

  

“为什么*ptr返回数组的基地址,它不应该返回该地址的值吗?”

执行返回该地址处的值,该地址为 数组arr

考虑排队的人:您可以指向第一个人并说“那边的那个人”,也可以指向同一个人并说“那边的那个人”。同一位置有 2 个东西:一个人和一个队列。数组也会发生同样的事情:person *代表“那边的人”,person (*)[42]代表“那排42人”。如果取消引用队列的指针,则会得到一个队列。如果您从队列中获得第一个,就会得到一个人。


但是然后,当数组本身作为printf的参数时,数组本身将衰减到 first 元素的 address 。因此,在这里,

int arr[] = { 3, 5, 6, 7, 9 }; 
int (*ptr)[5] = &arr;     

// undefined behaviour really, all pointers should be cast to void *
printf("%p %p %p %p", *ptr, &ptr[0], arr, &arr[0]);

所有这4个表达式将导致指向int的指针,其值是数组中第一个元素的地址(arr中3的地址)。

答案 2 :(得分:0)

这是一个简单的,较少技术性的解释。

您如何设置p= arr;

您如何设置ptr= &arr;

您的问题确实与数组完全无关。 arr可以是任何类型,并且答案将是相同的:&获取arr的地址,因此无论arr是什么,ptr都会存储其地址p本身存储arr时的地址。

如果您执行*ptr,则将取消引用该地址,从而获得等于p的值。

int arr = 3;
// clearly these are different!
int p = arr;
int* ptr = &arr;

类似地

int x = 3;
int* arr = &x;
// clearly these are different!
int* p = arr;
int** ptr = &arr;
// so of course they dereference differently
printf("*p = %d, *ptr = %p\n", *p, *ptr);

答案 3 :(得分:-1)

您看到的行为是'c'将arr解释为指向第一个元素的存储位置的指针的结果。指向数组&arr的指针将是该数组本身在内存中的地址,这也是其第一个元素的地址。结果,arr&arr产生相同的值。试试这个:

printf("array = %p, &array = %p\n", arr, &arr);

认为值相同,类型不同。 arr是变量,无论&arr是指向变量的指针。

ptr反映相同的图片。其值ptr = &arr使其成为数组的指针。它包含数组的地址。 *ptr返回数组本身,在'c'解释中是数组第一个元素的地址。结果,ptr*ptr的值与&arrarr的值相同。

希望它变得更清晰(而不是模糊):-)

答案 4 :(得分:-3)

数组是指针。 数组不是指针,请参见下面的注释

指向数组的指针是指向指针的指针。尝试两次取消引用,这应该产生一个值。