-1

我正在做一个小实验。

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

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

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

4

4 回答 4

6

首先要了解的是您要打印的内容:

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

表达式A[0]是一个左值表达式,其类型int[5]引用内部的第一个内部数组A,是一个指向数组&A的类型的右值表达式。finally等价于,即类型的左值表达式。int (*)[5][5]A*AA[0]int[5]

语言中没有定义(您也不能提供它们)将转储 aint[5]或 a的运算符int (*)[5][5],因此编译器尝试找到它可以找到的最佳匹配,并发现存在一个打印 a 的运算符void*int[5]可以衰减为int*引用 的a A[0][0],并且 that 本身可以转换为 a 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]);

遵循上面的推理,它必须具有相同的精确值,即使在第二种情况下类型不同。

于 2013-07-12T20:41:40.077 回答
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表示从地址 201 开始的完整二维数组,并且
  • &A给出完整二维数组的地址 = 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, *A,A都是相同的,但对称地不同。

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

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

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

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

如需更详细的解释,请务必阅读此答案

于 2013-07-12T20:38:03.127 回答
0

A[0] 这等价于 *(A + 0),或更简单地说是 *A。

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

于 2013-07-12T20:38:22.053 回答
0

数组,在最基本的层面上,是指向内存中某个点的指针。数组中的其他元素连续存储在该元素之后,并且索引告诉计算机从第一个元素跳转到所需的位置的位置。A[0]正在打印第一行中第一个元素的地址,&A正在打印 A 所在的地址,即第一行的第一个元素所在的地址,并且*A与 相同A[0]

于 2013-07-12T20:38:36.863 回答