二维数组 C++ 指针地址

Posted

技术标签:

【中文标题】二维数组 C++ 指针地址【英文标题】:2D array C++ pointer address 【发布时间】:2018-08-27 07:18:24 【问题描述】:
#include <stdio.h>
int main()

     int arr2D[3][3]; 
    printf("%d\n",((arr2D==*arr2D) && (*arr2D==arr2D[0]))); 
    return o;
    

存储在 *arr2D 和 arr2d 的值是相同的,而 arr2D 是一个常量指针,它将存储 第一个元素的地址 arr2D 表示 arr2D 指向的地址上的值?

【问题讨论】:

【参考方案1】:

如果我们在“纸”上画出你的数组,它会是这样的

+-------------+-------------+--------------+------- ------+-------------+--------------+-------------+- ------------+-------------+ | arr2D[0][0] | arr2D[0][1] | arr2D[0][2] | arr2D[1][0] | arr2D[1][1] | arr2D[1][2] | arr2D[2][0] | arr2D[2][1] | arr2D[2][2] | +-------------+-------------+--------------+------- ------+-------------+--------------+-------------+- ------------+-------------+

然后您必须记住,数组自然会衰减为指向其第一个元素的指针。当需要指针时,这是普通的arr2D,与&amp;arr2D[0] 相同。

现在,如果我们“重绘”数组,但仅针对 arr2D[0](这与您的问题最相关)以及一些可能的指针:

+-------------+-------------+-------------+-----+ | arr2D[0][0] | arr2D[0][1] | arr2D[0][2] | ... | +-------------+-------------+-------------+-----+ ^ | &arr2D[0] | &arr2D[0][0]

由于我们知道arr2D&amp;arr2D[0] 相同,因此我们可以在表达式arr2D == *arr2D 中进行替换。这让我们&amp;arr2D[0] == *&amp;arr2D[0]

取消引用* 和地址&amp; 运算符相互抵消,所以我们有&amp;arr2D[0] == arr2D[0]

现在跟上...我们知道数组衰减为指向其第一个元素的指针,并且我们知道arr2D[0] 是一个数组;这意味着它将衰减到&amp;arr2D[0][0],留下表达式&amp;arr2D[0] == &amp;arr2D[0][0]。如图所示,这两个地址是相同的,这意味着比较是正确的。

重要提示:虽然&amp;arr2D[0]&amp;arr2D[0][0] 可能都指向同一个位置,但它们的类型是不同的。 &amp;arr2D[0] 的类型是int (*)[3],而&amp;arr2D[0][0] 的类型是int *


有了上述信息,应该很容易理解另一个比较*arr2D == arr2D[0],尤其是因为已经提到了所有部分。

【讨论】:

【参考方案2】:

这不是有效的 C 代码。

arr2D 在表达式中使用时会衰减为指向第一个元素 int (*)[3] 的指针。而*arr2D 给出二维数组的第一项,int[3],在表达式中使用时也会衰减为int*

因此代码将int (*)[3]int* 进行比较。它们不是兼容的指针类型并且无法进行比较 - 这是违反标准 (C17 6.5.9/2) 的约束,编译器必须生成诊断消息。这意味着这是一个严重的错误,任何想在符合标准的 C 编译器中尝试代码的人都会发现它。

根据[] 运算符的定义,*arr2Darr2D[0] 始终是等价的。

代码打印的是任何人的猜测,因为包含违反约束的代码将被视为具有未定义的行为。

【讨论】:

以上是关于二维数组 C++ 指针地址的主要内容,如果未能解决你的问题,请参考以下文章

C++建立动态二维数组

C++ new申请二维数组整理

c++二维数组和二级指针

C++二维数组(指针)做参数

怎么让一个二维指针指向一个二维数组

c++如何用指针指向二维数组