2016-09-29 47 views
-8
#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; 
    } 

结果是:关于指针短C++程序

0x28fef8 0x28fef8 0x28fef8 
0x28fef8 1  0x28fef8 
0x28fef8 

为什么x[0][0]和x是在同一指针?什么是0x28fef8真的? 1或0x28fef8?

回答

4

像您数组的数组看起来像这样在存储器

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

xx[0]x[0][0]的位置是一样的。

另外,数组自然衰变到指向其第一个元素的指针。如果您使用普通x,您将获得&x[0]。如果您使用x[0],您将获得&x[0][0]。因此,当您执行*x[0]时,它与执行*&x[0][0]的操作相同,并且操作员的取消引用和地址相互抵消,因此您只剩下x[0][0],这是您打印的值。

此外,为了帮助你理解为什么x是一样的&x[0],你需要知道的是,对于任何阵列或指针x和索引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] 

虽然所有的xx[0]&x&x[0]&x[0][0]可能代表相同的内存地址,他们在语义上是不同的,我。È它们代表不同的类型:

  • x是一个指针到三个char(或char (*)[3]
  • x[0]的阵列是一个指向char(或char *
  • &x是指向的数组3 char(或char (*)[3][3]
  • &x[0]阵列是三个char(或char (*)[3])的阵列的指针
  • &x[0][0]是指向char(或char *
+0

@molbdnilo我不会说'* x [0]'衰减,我说'x [0]'(注意缺乏解引用操作符)会衰减。 –

+0

哦,*现在*我明白你的观点...(今天有点厚)。我从不认为'* array'是“衰减指针,然后解引用”,而是“完全等同于'array [0]',但使用不同的语法”。 – molbdnilo

+0

非常感谢。我想我明白了。但是地址0x28fef8究竟是什么? 1或0x28fef8,您会看到&x = x = 0x28fef8 =&x [0] [0]。 – Ken

0

当阵列的名称满足的sizeof()它返回的sizeof阵列,当阵列的名字满足&,它返回一个指针阵列,而不是地址数组名称。