2D阵列的行为

时间:2014-07-16 22:32:39

标签: c++ c arrays pointers output

我创建了一个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 *,2D数组被视为一维数组,因此a+1充当2nd元素的指针,因此我们得到的输出为2

我的假设是否正确或背后是否有其他逻辑?
另外,最初将a视为指针int (*)[2]int **时的类型是什么?

4 个答案:

答案 0 :(得分:10)

当你写表达式

(int *)a

然后逻辑上原始数组可以通过以下方式被视为一维数组

int a[4] = { 1, 2, 3, 4 };

因此表达式a指向第一个元素,该元素等于这个虚构数组的1。表达式( a + 1 )指向虚数组的第二个元素等于2,而表达式( a + 1 )[0]返回对此元素的引用,即得到2。

答案 1 :(得分:9)

  

我的假设是正确的还是还有其他一些逻辑?

是。

*(a+1)[0]相当于a[1][0] ((int *)a+1)[0]相当于a[0][1]

说明:

a衰减指向2D数组的第一个元素,即指向第一行。 *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]

答案 2 :(得分:3)

2D数组本质上是一个具有一些额外编译器知识的单维数组。

当您将a转换为int*时,您会删除此知识,并将其视为普通的一维数组(在您的情况下,它会在内存中查找1 2 3 4)。< / p>

答案 3 :(得分:0)

这里要认识到的关键是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]