[英]Behavior of 2D arrays
我创建了一个2D数组,并尝试打印某些值,如下所示:
int a[2][2] = { {1, 2},
{3, 4}};
printf("%d %d\n", *(a+1)[0], ((int *)a+1)[0]);
输出是:
3 2
我理解为什么3
是第一个输出( a+1
指向第二行,我们打印它的0th
元素。
我的问题是关于第二个输出,即2
。 我的猜测是,由于类型转换a
作为int *
,二维数组可视为一维数组,因而a+1
作为指针2nd
元素,依此,我们得到的输出作为2
。
我的假设是正确的还是背后还有其他一些逻辑?
而且,原本是什么的类型a
时作为指针处理int (*)[2]
或int **
?
当你写表达式
(int *)a
那么逻辑上原始数组可以通过以下方式被视为一维数组
int a[4] = { 1, 2, 3, 4 };
所以表达a
指向第一个元素,等于这个虚构数组的1。 表达式( a + 1 )
指向虚数组的第二个元素等于2,而表达式( a + 1 )[0]
返回对此元素的引用,即得到2。
我的假设是正确的还是背后还有其他一些逻辑?
是。
*(a+1)[0]
相当于a[1][0]
。
((int *)a+1)[0]
相当于a[0][1]
。
说明:
a
衰减到指针二维数组的第一元素,即,与第一行。 *a
取消引用该行是2 int
的数组。 因此, *a
可以被视为第一行的数组名称,它进一步衰减到指向其第一个元素的指针,即1
。 *a + 1
将指向第二个元素。 解除引用*a + 1
将给出1
。 所以:
((int *)a+1)[0] == *( ((int *)a+1 )+ 0)
== *( ((int *)a + 0) + 1)
== a[0][1]
注意, a
, *a
, &a
, &a[0]
和&a[0][0]
都具有相同的地址值,尽管它们的类型不同。 衰减后, a
的类型为int (*)[2]
。 将它转换为int *
只是使地址值为int *
类型,而算术(int *)a+1
给出第二个元素的地址。
另外,最初什么是被视为指针的类型
(int (*)[2]
或int **
?
它成为2 int
数组的类型指针 ,即int (*)[2]
2D数组本质上是一维数组,具有一些额外的编译器知识。
当你施放a
以int*
,为您免除这方面的知识,而且它当作一个正常的单维数组(而你的情况看起来像内存1 2 3 4
)。
这里要认识到的关键是a
保存第一行所在地址的值。 由于整个数组从相同的位置开始,整个数组也具有相同的地址值; 同样的第一个元素。
用C
表示:
&a == &a[0];
&a == &a[0][0];
&a[0] == &a[0][0];
// all of these hold true, evaluate into 1
// cast them if you want, looks ugly, but whatever...
&a == (int (*)[2][2]) &a[0];
&a == (int (*)[2][2]) &a[0][0];
&a[0] == (int (*)[2]) &a[0][0];
因此,当你将a
为int *
,它只是通过类型和值变为&a[0][0]
相当的1对1。 如果您要将这些操作应用于&a[0][0]
:
(&a[0][0] + 1)[0];
(a[0] + 1)[0];
*(a[0] + 1);
a[0][1];
至于类型a
时作为指针处理,虽然我不能肯定,应该是int (*)[2]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.