取消引用指向整个数组的指针
Posted
技术标签:
【中文标题】取消引用指向整个数组的指针【英文标题】:Dereferencing pointer to entire array 【发布时间】:2015-10-25 05:45:09 【问题描述】:我正在学习 C 中指向(整个)数组的指针。
假设我声明了一个二维整数矩阵:
int arr[3][3] =
1, 2, 3,
4, 5, 6,
7, 8, 9
;
现在,我声明一个适当类型的指针:
int (*ptr)[3][3];
初始化它:
ptr = &arr;
现在,ptr 包含 arr 的地址。
ptr --->&(arr[0][0] arr[0][1] arr[0][2]
arr[1][0] arr[1][1] arr[1][2]
arr[2][0] arr[2][1] arr[2][2])
所以,当我们取消引用 ptr 时,它应该产生第一个位置,不是吗?
printf("%d", *ptr)
在编译时给出错误。要打印第一个元素,我必须使用***ptr
。
我有两个问题:
-
我无法理解三重取消引用的必要性。
如果
*ptr
不指向数组的第一个元素,它指向什么
到?
【问题讨论】:
您为什么希望*&arr
引用arr[0][0]
而不是arr
?这就像期望 *&some_int
引用 int 的第一个字节,而不是整个 int。
我很困惑,因为 int 是原始类型,而数组是原始类型的集合。与 int 不同,打印数组需要遍历它的所有元素。
【参考方案1】:
printf(*ptr);
是错误的,因为printf
的第一个参数需要是一个字符串,该字符串指定用于打印其余参数的格式。要打印地址,请使用:
printf("%p", *ptr);
我无法理解三重取消引用的必要性。
p
的类型是int (*)[3][3]
。
*p
的类型是int [3][3]
。
**p
的类型是int [3]
***p
的类型是int
。
当你有这样的指针时,最好使用数组语法。
(*p)[0][0]
一般形式是:
(*p)[i][j]
这比使用***p
更容易混淆。此外,***p
只能用于访问数组的[0][0]-th
元素。
如果
*ptr
不指向数组的第一个元素,它指向什么?
希望上一个问题的答案能解释这一点。
【讨论】:
感谢您的解释!明白了。%p
期望 void*
。所以你触发了UB。应该是printf("%p", (void*)*ptr);
@tstanisl,任何对象指针都可以在需要void*
的地方使用。我不明白为什么省略显式演员会导致 UB。
@RSahu,因为 C 标准不要求指针类型具有与 void*
相同的二进制表示。标准未定义int*
类型的序列化指针并将其反序列化为void*
。因此,必须进行演员表才能便携以上是关于取消引用指向整个数组的指针的主要内容,如果未能解决你的问题,请参考以下文章