当 p 是二维数组时,为什么 p、*p 和*p 具有相同的值?
Why p, *p, &*p have the same value when p is a two dimension array?
当 p
是数组的指针时,为什么:
*p == p == &*p
简单程序,只是C 中的二维数组:
int p[][3] = {{1,2,3}};
cout << p << " " << *p << " " << &*p;
结果:0x22Fe20 0x22Fe20 0x22Fe20
阵列p
在打印时腐烂到指向其第一个元素的指针。这与&p
相同。至于&*p
,这是 p
指向的任何指数的地址。这再次是第一个元素 - 与前两个相同。
类型不同。即使地址相同。p
是一个数组,但是&p
是int
数组的指针。
使用数组的值(在这种情况下为p
(时,它会隐式将指针转换为第一个元素(与&p[0]
相同(。这种转换称为衰减。
另外,数组的第一个元素位于数组所在的同一地址。
-
p
腐烂到&p[0]
。它是p
的第一个元素的地址,该地址与数组p
本身相同。 -
*p
在这里,p
首先衰减到&p[0]
,因此完整的表达式等效于*&p[0]
。*&
相互取消(根据C; C 中的定义使用不同的措辞,但效果是相同的(,因此它是p[0]
的LVALUE,即数组的第一个元素。在这种情况下,该元素是另一个数组,因此其值衰减到指向第一个元素的指针(即&p[0][0]
(。由于第一个元素的地址与数组的地址相同,因此p[0][0]
的地址与p[0]
的地址相同,该地址与p
的地址相同。 -
&*p
和以前一样,&*
相互取消,结果与仅使用p
。
在内存中,一个4x4 2D阵列看起来像这样:
*
..0000111122223333..
XXXXXXXXXXXXXXXX
YYYY
Z
在此图中,每列代表一个内存位置。用X
标记的列是存储2D阵列的位置。
标记为0的每列是第一个子阵列的一个元素,每个列是第二个子阵列的元素等。
。用Y
标记的列是存储第一个子阵列的位置。
用Z
标记的列是第一个子阵列的第一个元素。
您可能会注意到,X
,Y
和Z
都以*
标记的相同地址开始。这是数组的地址,第一个子阵列的地址和第一个子阵列的第一个元素的地址。
p
是指向数组开始的指针。
*p
是指向该数组中第一个数组的指针(又称数组的开头(
&*p
与 p
是同一件事。
如果您声明了一个数组,例如这样
int a [] = {1,2,3};
然后在表达式中使用(如罕见例外,例如操作员大小的操作数(,该数组指定器被隐式转换为指针转换为其第一个元素。所以在这个语句中
std::cout << a;
与
相同std::cout << &a[0];
或与
相同std::cout << &*a;
在您的示例中,*p
是一个数组{1,2,3}
,代表数组p
的第一个元素。
用作语句中的表达
std::cout << *p;
它被转换为其第一个元素的地址,它是第一个元素的地址等于1。
所有这些地址都指向分配给数组的程度的开始。因此,尽管例如表达式p
和表达式*p
的类型是不同的(第一个表达式具有int ( * )[3]
类型,而第二个表达式具有类型int *
(,但它们的值仍然相等。
- 将值从二维数组输出到文本文件
- 在二维数组中查找最小值和最大值?
- 移动二维数组中的字符
- 如何正确填充在堆上分配的二维数组?
- 传递二维数组时出现问题
- 具有随机数的二维数组不会更改
- 如何在C++中获取二维数组中最少的一列数?
- 如何使用用户输入变量制作二维数组?
- 为什么指针在对二维数组进行排序时无法正常工作?
- 为什么我需要三个嵌套的大括号来调用赋值运算符,将const引用到二维数组
- 当 p 是二维数组时,为什么 p、*p 和*p 具有相同的值?
- 为什么这个指针到指针的二维数组像这样分配新的 int
- 动态分配缓冲空间为二维数组 - 为什么失败
- 为什么二维数组中的Range是这样写的
- 为什么在尝试用c++创建二维数组时会出现此错误
- 为什么我将数字数据从文本文件导入二维数组的代码不起作用
- 为什么使用一维数组而不是二维数组?
- 在c++的二维数组中,为什么我们总是要提到列数
- 为什么我可以声明一个二维数组与两个维度大小的变量,但不是新的
- 为什么在声明二维数组时需要硬编码宽度