繁体   English   中英

2D阵列的行为

[英]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数组本质上是一维数组,具有一些额外的编译器知识。

当你施放aint* ,为您免除这方面的知识,而且它当作一个正常的单维数组(而你的情况看起来像内存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];

因此,当你将aint * ,它只是通过类型和值变为&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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM