#include <iostream>
using namespace std;
int main()
{
int x[][3]={1,2,3,4,5};
cout<<&x <<" "<<*x <<" "<<x <<endl;
cout<<&x[0]<<" "<<*x[0]<<" "<<x[0]<<endl;
cout<<&x[0][0]<<endl;
return 0;
}
结果是:
0x28fef8 0x28fef8 0x28fef8
0x28fef8 1 0x28fef8
0x28fef8
为什么x[0][0]
和x在同一个指针中?什么是真正的0x28fef8? 1还是0x28fef8?
答案 0 :(得分:4)
像你这样的数组数组在内存中看起来像这样
+---------+---------+---------+---------+---------+---------+ | x[0][0] | x[0][1] | x[0][2] | x[1][0] | x[1][1] | x[1][2] | +---------+---------+---------+---------+---------+---------+
x
,x[0]
和x[0][0]
的位置完全相同。
此外,数组自然衰减到指向第一个元素的指针。如果您使用普通x
,则会获得&x[0]
。如果您使用x[0]
,则会获得&x[0][0]
。因此,当您执行*x[0]
时,它与执行*&x[0][0]
相同,并且运算符的取消引用和地址相互抵消,因此您将留下x[0][0]
,这是您打印的值
此外,为了帮助您理解为什么x
与&x[0]
相同,您需要知道任何数组或指针 x
和索引{ {1}}表达式i
与x[i]
相同。这意味着表达式*(x + i)
与&x[i]
相同,并且由于地址和解除引用运算符再次相互取消&*(x + i)
与&x[i]
相同(或者没有括号(x + i)
)。现在想想x + i
为零时的情况,然后我们i
与&x[0]
相同,x + 0
与x
相同。因此&x[0]
与x
相同,反之亦然。
对于那些想知道&x
以及&x[0]
和&x[0][0]
代表什么的人,请看这个:
+---------+---------+---------+---------+---------+---------+ | x[0][0] | x[0][1] | x[0][2] | x[1][0] | x[1][1] | x[1][2] | +---------+---------+---------+---------+---------+---------+ ^ ^ ^ ^ | | | | +- &x +- &x[0][1] +- &x+1 +- &x[1][1] | | +- &x[0] +- &x[1] | | +- &x[0][0] +- &x[1][0]
虽然所有x
,x[0]
,&x
,&x[0]
和&x[0][0]
可能代表相同的内存地址,但它们在语义上是不同的,即它们代表不同类型:
x
是指向三个char
(或char (*)[3]
)x[0]
是指向char
(或char *
)&x
是指向三个char
(或char (*)[3][3]
)&x[0]
是指向三个char
(或char (*)[3]
)&x[0][0]
是指向char
(或char *
)答案 1 :(得分:0)
当数组的名称符合sizeof()时,它返回数组的大小,当数组的名称符合&amp;时,它返回一个指向数组的指针,而不是数组的地址&#39; s名。