2013-07-12 122 views
-1

我做了一个小实验。为什么值输出为相同A [0],&A,和* A?

#include<cstdio> 
#include<iostream> 
using namespace std; 
int main() 
{ 

    int A[5][5]; 
    cout<<A[0]<<" "<<&A<<" "<<*A; 
    return 0; 
} 

它为所有情况打印相同的值。有人可以解释为什么会出现这种情况吗?

+4

什么是你期待它打印? –

+2

这已经被问过。 'A [0]'是第一个元素,它衰减成要打印的指针,'&A'是地址,它是相同的地址,而'* A'与第一个地址相同。 – chris

+0

那么A [0]显示A [0] [0]的地址? –

回答

1

A[0],&A,*A都是指向不同类型的指针,它们指向相同的内存位置。相同的价值(种类),不同的类型。

Expression Symmetric           Type 
---------------------------------------------------------------------------- 
A   address of first row.        int[5][5] 
&A[0][0] address of first element       int* 
&A   address of 2d array         int(*)[5][5] 
*A   = *(A + 0) = A[0] = address of first element  int[5] = decays to int* 
                     in a expression 

我的5×4尺寸字符数组的例子:

     A 
        +---201---202---203---204---206--+ 
    201    | +-----+-----+-----+-----+-----+| 
    A[0] = *(A + 0)--►| 'f' | 'o' | 'r' | 'g' | 's' || 
    207    | +-----+-----+-----+-----+-----+| 
    A[1] = *(A + 1)--►| 'd' | 'o' | '\0'| '\0'| '\0'|| 
    213    | +-----+-----+-----+-----+-----+| 
    A[2] = *(A + 2)--►| 'n' | 'o' | 't' | '\0'| '\0'|| 
    219    | +-----+-----+-----+-----+-----+| 
    A[3] = *(A + 3)--►| 'd' | 'i' | 'e' | '\0'| '\0'|| 
        | +-----+-----+-----+-----+-----+| 
        +--------------------------------+ 

大约图形例的简要说明。

  • 在图A表示完整的2 d阵列地址201开始,并
  • &A给出完整的2 d阵列的地址= 201
  • *A = *(A + 0) = A[0]点到第一行= 201
  • 注意值A[0][0]'f'在我的例子中,&A[0][0]给出的地址[0][0]元素= 201
  • &A[0][0]是一样*A,因为&A[0][0] =>&(*(*A)) =>&**A =>*A

因此,所有A[0]&A*AA是相同的,但不同的对称。

观察A[0]&A*AA之间的差异。键入以打印sizeof()信息。例如

cout<<sizeof(A[0]) <<" "<<sizeof(&A) <<" "<<sizeof(*A) <<" "<< sizeof(A); 

第二个尝试使用打印下一个位置地址:

cout<<(A[0] + 1)<<" "<<(&A + 1) <<" "<<(*A + 1)<<" "<<(A + 1); 

对于更详细的解释,一定要读这answer

+0

是啊,我不知道为什么这个问题有一个[c]标签。在C中没有'std :: cout'。 –

+0

对不起编辑我的答案! – haccks

+0

这不是C的问题.C中没有'std :: cout'。 –

0

A [0]这相当于*(A + 0),或更简单地* A。

& A是多一点棘手。 A的类型为int [5] [5],它由堆栈上的100个字节的连续区域表示。 A的地址是该区域的开始 - 这等于指向第一个元素的指针。第一个元素地址也是* A的存储位置。

+4

你怎么知道它是100字节? – 2013-07-12 20:40:02

+0

是的,解释一下。请....... – haccks

+0

来吧......不是标准的,而是在所有非DSP非嵌入式平台上存在sizeof(int)== 4'。这些评论会有点用处:*你正在假设一个架构,其中sizeof(int)== 4 * *。顺便说一句,Norwæ,你假设32位整数! –

0

的阵列,在其最基本的水平,是一个指针,指向存储器中的点。数组中的其他元素是元素之后连续存储和索引告诉计算机如何很多地方,从第一个元素跳得到所需之一。A[0]被打印出的第一个元素的地址的第一行中,&A正在打印是A位于地址,这是在第一行的第一个元素是,和*A相同A[0]

6

首先要明白的是你要打印的内容:

cout<<A[0]<<" "<<&A<<" "<<*A; 

表达A[0]左值表达式类型int[5]指内A第一内部阵列,&Aint (*)[5][5]类型的右值,表达式指向数组A。最后*A相当于A[0],即int[5]类型的左值表达式。

没有在语言定义的运营商(你也不能为他们提供),将转储无论是int[5]int (*)[5][5],所以编译器将尝试查找最好匹配它可以和认为,没有一个操作符打印一张void*int[5]可以衰变成一个int*引用A[0][0],那就是本身转化成void*int (*)[5][5]是一个指针,因此可转换为void*,所以过载对两种情况均有效。

该语言定义了内存中数组的布局,特别是它要求数组和阵列的第一个元素布局在同一个内存地址中,所以如果要打印地址&A&A[0]它将打印相同的值,并且因为&A[0]也是在其第一元件的同一存储器位置,&A[0][0]也指相同的地址。

让我们再回到上面的代码要打印的是:

cout<<   static_cast<void*>(&A[0][0]) 
    << " " << static_cast<void*>(&A) 
    << " " << static_cast<void*>(&A[0][0]); 

其按照上述推理必须具有相同的精确值,即使类型不是在第二种情况下是相同的。

相关问题