对于“int demo [4] [2]”,为什么所有这些都是相同的:& demo [1],demo [1],demo + 1,*(demo + 1)?类型怎么样?

时间:2013-05-13 07:14:13

标签: c pointers multidimensional-array pointer-arithmetic

正当我放松思考我对数组上下文中的指针有一个公平的理解时,我已经在下面的程序中再次面朝下。我已经理解了数组arr,{{1} }和arr在数量上都是相同的,但在类型上有所不同,但我无法牢牢掌握以下程序的输出。我试图将其可视化但仅部分成功。如果你能给出一个,我将不胜感激这个东西的严谨和详细的解释,以便像我这样的人可以完成这种混乱。

在下面的程序中,我使用了“2D”数组&arr。我知道demo[][2]将是demo[],大小为2.我也知道{{1}单独使用将是array of arrays类型。仍然我对以下内容感到茫然:

1)为什么demo(*)[2]相同?是不是&demo[1]应该是第二个数组的地址?究竟是什么{ {1}}然后为什么它与第二个数组的地址相同?

2)我知道第二个demo[1]和第四个相同,因为demo[1]只是&demo[1]。但我已经使用了它说明这一点。它如何等于第三个printf(),即 demo + 1 如何等于 *(demo + 1)?与demo[1]相同的*(demo+1)是众所周知的,但printf()如何等于demo[1]“某事”如何等于“某事”的价值

3)因为它刚刚证明我不是很聪明,所以我应该停止猜测游戏,并要求你就类型的含义做出决定性的答案。以下:

&安培;演示[1]
演示[1]
demo + 1

*(demo+1)

输出:

demo+1

3 个答案:

答案 0 :(得分:2)

demo[1]是数组demo的第二个成员,它本身就是一个数组。就像任何其他数组一样,当它不是&sizeof运算符的主题时,它会求值为指向其第一个元素的指针 - 也就是说,demo[1]的计算结果与&demo[1][0],数组int中第一个demo[1]的地址。

&demo[1]是数组demo[1]的地址,因为数组的地址和该数组的第一个成员的地址必须是同一个位置,&demo[1]是相同的至&demo[1][0],等于裸demo[1]。这是关键洞察力 - 数组的第一个元素与数组本身位于内存中的相同位置,就像struct的第一个成员位于内存中与结构本身相同的位置。当您打印&demo[1]demo[1]时,您不会打印指向数组和数组的指针;你正在打印一个指向数组的指针和一个指向该数组的第一个成员的指针。

demo+1demo第二个成员的地址。 *(demo+1)是该成员本身(它是数组demo[1]),但因为该成员是一个数组,所以它计算为指向其第一个成员的指针。如上所述,其第一个成员必须与阵列本身并置。并不是说“某事”等于“某事”的价值 - 因为当你在这样的表达式中使用数组时,它不会对数组本身进行求值。

  • &demo[1]demo[1]的指针,是int的数组。所以它的类型是int (*)[2]
  • demo[1]是一个2 int的数组。它的类型是int [2]。但是,当在表达式中使用它不是类型&sizeof运算符的主题时,它将计算为指向其第一个成员的指针,该成员是类型为int *的值
  • demo+1是指向demo[1]的指针,其类型为int (*)[2]

答案 1 :(得分:0)

考虑数组如何在内存中布局:

   +-----+-----+-----+-----+-----+-----+-----+-----+
   |  13 |  45 |  83 |  34 |   4 |   8 | 234 | 934 |
   +-----+-----+-----+-----+-----+-----+-----+-----+
   ^           ^           ^           ^
   |           |           |           |
demo[0]     demo[1]     demo[2]     demo[3]

然后还记得自然demo“指向”数组中的第一个条目。从这一点可以看出,demo + 0当然也应该指向第一个条目,另一种获取数组中条目地址的方法是使用操作数&的地址,它将是{{} 1}}。因此&demo[0]等于demo,等于demo + 0

还要记住,对于您的示例,&demo[0]中的每个条目都是另一个数组,并且数组和指针几乎可以互换(因为数组会衰减到指针)。由此可见demo也可以用作指针。

现在用demo[0]替换上面的0索引,你就得到了与观察完全相同的东西。

答案 2 :(得分:0)

                        +-------+------+
                        |       |      |
                        |   13  |  45  |
                   101  |       |      | 105
                        +--------------+
                        |       |      |
                        |   83  |  34  |
                   109  |       |      | 113 
                        +--------------+
                        |       |      |
                        |   04  |  08  |
                   117  |       |      | 121 
                        +--------------+
                        |       |      |
                        |   234 | 934  |
                   125  |       |      | 129 
                        +--------------+

注意:假设sizeof(int) = 4

假设2D布局(虽然在内存中不是这样,但它们都在一致)

demo[i]是2D数组的i th 行。它们本身就是一维数组。 demo[1]1 th 行。 [我的意思是地址109]。

&demo[1] 

demo[1]的地址,与该行的基地址相同。就像1D数组一样。数组名称给出第一个位置的地址。这里的一维数组名称为demo[1]

demo[1] 

因为数组名也给出了数组的基地址,它与&demo[1]

相同

demo+1

demo是指针,值为101demo(即demo[0])属于第1行[劣质描述。我的意思是具有两个元素的行的大小 - (*)[2]]因此demo+1将其递增以指向下一行。这是demo[1]

的理智
*(demo+1)

demo+1 is the 1<sup>th</sup> row 

*(demo+1)表示该位置的值。这本身就是一个数组,因此它给出了地址。因为数组名称给出了地址