取消引用指向整个数组的指针

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*。因此,必须进行演员表才能便携

以上是关于取消引用指向整个数组的指针的主要内容,如果未能解决你的问题,请参考以下文章

取消引用指针和访问数组元素之间的区别

通过取消引用更改 NSArray 中的值?

如何根据它们指向的值对双指针数组进行排序?

一级指针,二级指针,指针数组,数组和指针

指向指针的指针如何能够引用数组

指向整个数组的C ++指针[重复]