#include<bits/stdc++.h>
using namespace std;
int main()
{
int a[101][101];
a[2][0]=10;
cout<<a+2<<endl;
cout<<*(a+2)<<endl;
cout<<*(*(a+2));
return 0;
}
为什么a + 2和*(a + 2)的值相同?提前谢谢!
答案 0 :(得分:5)
a
是一个2D数组,表示一个数组数组。但是当在适当的上下文中使用时,它衰减指向数组的指针。所以:
a+2
中,a
衰减到指向大小为101的int数组的指针。当你传递给ostream时,你得到这个数组的第一个元素的地址,即{{ 1}} &(a[2][0])
:它是一个大小为101的数组,从*(a+2)
开始。它衰减到指向int的指针,当你将它传递给ostream时,你得到它的第一个元素的地址,它仍然是a[2]
a[2][0]
<{em> &(a[2][0])
。当你将它传递给ostream时,你得到它的int值,这里是10。但要注意:**(a+2)
和a[2][0]
都是指向同一地址的指针(a + 2
与a[2]
相同),但它们是指向不同类型的指针:指向大小为101的int数组,后者为int。
答案 1 :(得分:1)
二维数组是一个数组数组,因此它在内存中存储如下:
char v[2][3] = {{1,3,5},{5,10,2}};
Content: | 1 | 3 | 5 | 5 | 10 | 2
Address: v v+1 v+2 v+3 v+4 v+5
要访问v [x] [y],编译器会将其重写为:*(v + y * M + x)
(其中M是指定的第二个维度)
例如,要访问v [1] [1],编译器会将其重写为*(v + 1*3 + 1)
=&gt; *(v + 4)
请注意, 与指针指针(char **)相同。 指向指针的指针不是数组:它包含存储单元的地址,并包含另一个地址。
要使用指向指针的指针访问二维数组的成员,请执行以下操作:
char **p;
/* Initialize it */
char c = p[3][5];
p
; 通过传统的二维数组访问成员时,这些步骤是:
char p[10][10];
char c = p[3][5];
p
的地址并将第一个偏移量(3)加上一行(10)的维数。答案 2 :(得分:1)
如果您有这样的数组
T a[N];
然后将数组的名称隐式转换为指向其第一个元素的指针,但极少数例外(例如在sizeof
运算符中使用数组名称)。
因此,例如,在表达式( a + 2 )
中,a
转换为T *
类型&a[0]
。
相对于您的示例wuth数组
int a[101][101];
表达式中的
a + 2
a转换为int ( * )[101]
类型的右值并指向数组的第一个“行”。 a + 2
指向数组的第三个“行”。行的类型为int[101]
表达式*(a+2)
为第三行提供了类型int[101]
的数组。并且依次在表达式中使用的该数组将转换为指向其第一个int *
类型元素的指针。
它与第三行占用的内存区域的起始地址相同。
只有表达式( a + 2 )
的类型为int ( * )[101]
,而表达式*( a + 2 )
的类型为int *
。但是两者都产生相同的值 - 数组a
的第三行占用的内存区域的起始地址。
答案 3 :(得分:0)
数组的第一个元素与数组本身位于同一位置 - 没有&#34;空格&#34;在数组中。
在cout << a + 2
中,a
被隐式转换为指向其第一个元素&a[0]
的指针,而a + 2
是a
&#39的位置;第三个元素&a[2]
。
在cout << *(a + 2)
中,数组*(a + 2)
- 即a[2]
- 将转换为指向其第一个元素&a[2][0]
的指针。
由于a
的第三个元素的位置和a
的第三个元素的第一个元素的位置相同,因此输出相同。
答案 4 :(得分:0)
我将尝试解释编译器如何映射内存:
让我们考虑一个更实际的多维数组示例:
int a[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
您可以执行命令
x/10w a
在GDB中查看内存:
0x7fffffffe750: 1 2 3 4
0x7fffffffe760: 5 6 7 8
0x7fffffffe770: 9 0
每个元素都存储在 int 类型中( 32位/ 4字节)。 所以矩阵的第一个元素已存储在:
1) a[0][0] -> 0x7fffffffe750
2) a[0][1] -> 0x7fffffffe754
3) a[0][2] -> 0x7fffffffe758
4) a[1][0] -> 0x7fffffffe75c
5) a[1][1] -> 0x7fffffffe760
6) a[1][2] -> 0x7fffffffe764
7) a[2][0] -> 0x7fffffffe768
...
命令:
std::cout << a + 2 << '\n'
它会打印地址 0x7fffffffe768 因为 指针aritmetic: a 的类型为 int ** ,因此它是指向指针的指针。 a + 2是a [0](第一行)+ 2.结果是指针 到第三排。
*(a + 2)推断第三行,即{7,8,9}
第三行是int数组,这是一个指向int的指针。
然后运营商&lt;&lt;将打印该指针的值。