【问题标题】:For "int demo[4][2]",why are all these same in magnitude: &demo[1],demo[1],demo+1,*(demo+1) ?What about type?对于“int demo[4][2]”,为什么所有这些大小都相同:&demo[1],demo[1],demo+1,*(demo+1)?类型呢?
【发布时间】:2013-05-13 07:14:12
【问题描述】:

就在我放松地思考我对数组上下文中的指针有一个公平的理解时,我再次面对下面的程序。我已经理解了数组arrarr和@987654323的用法@ 大小相同,但类型不同,但我无法牢牢掌握以下程序的输出。我尝试将其可视化,但仅部分成功。如果您能对此给出严格而详细的解释,我将不胜感激这样一来,像我这样的人就可以永远摆脱这种混乱。

在下面的程序中,我使用了一个“二维”数组demo[][2]。我知道demo[] 将是一个大小为2 的array of arrays。我也知道单独使用的demo 将是@ 类型987654328@.我仍然对以下内容感到茫然:

1) 为什么&demo[1]demo[1]一样?demo[1]不应该是第二个数组的地址吗?那么&demo[1]到底是什么,为什么是和第二个数组的地址一样吗?

2) 我知道第二个printf() 和第四个是一样的,因为demo[1] 只不过是*(demo+1)。但我已经用它来说明这一点。如何能不能等于第三个printf(),即demo+1怎么能等于*(demo+1)demo[1]*(demo+1) 相同是众所周知的,但demo+1 怎么可能等于*(demo+1)“某物”如何与该“某物”的价值相等

3) 既然这证明我不是很聪明,我应该停止猜谜游戏,并请你就什么是类型以下:

&demo[1]
演示[1]
演示+1

#include<stdio.h>

int main(void)
{
    int demo[4][2]= {{13,45},{83,34},{4,8},{234,934}};
    printf("%p\n",&demo[1]);
    printf("%p\n",demo[1]);  //Should have cast to (void*),but works still
    printf("%p\n",demo+1);
    printf("%p\n",*(demo+1));
}

输出:

0023FF28
0023FF28
0023FF28
0023FF28

【问题讨论】:

  • 发现 *demo[1] 给出 83,第二个数组的一个元素。

标签: c pointers multidimensional-array pointer-arithmetic


【解决方案1】:

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

&amp;demo[1] 是数组demo[1] 的地址,由于数组的地址和该数组的第一个成员的地址必然是同一个位置,所以&amp;demo[1] 等于&amp;demo[1][0],即等于裸demo[1]。这是关键的见解 - 数组的第一个元素与数组本身位于内存中的相同位置,就像 struct 的第一个成员与结构本身位于内存中的相同位置一样。当您打印&amp;demo[1]demo[1] 时,您不会打印指向数组和数组的指针;您正在打印指向数组的指针和指向该数组第一个成员的指针。

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

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

【讨论】:

  • +1 措辞非常好的答案。第二个维度以及 demo+1demo[1]&amp;demo[1] 的加法 等价物,值得注意的是其中的第二个,否则一维数组中不会出现这种情况,它们的布局非常好出去。我希望我可以再次投票支持类型描述中的第二个项目符号,特别是 int (*)[2]int * 之间的区别,以及原因。
  • @WhozCraig 我的老朋友,也请看一下 caf 已回答的问题,并将您的有用/有用的评论也留在那里。 stackoverflow.com/questions/16514806/…
  • @Rüppell'sVulture 咖啡馆在该问题中的回答同样可靠。我想我看到那里形成了一种模式=P。我想我不能回答得更好了。
【解决方案2】:

想想数组在内存中是如何布局的:

+-----+-----+------+-----+-----+-----+---+-----+ | 13 | 45 | 83 | 34 | 4 | 8 | 234 |第934章 +-----+-----+------+-----+-----+-----+---+-----+ ^ ^ ^ ^ | | | | 演示[0] 演示[1] 演示[2] 演示[3]

那么还要记住demo“指向”数组中的第一个条目。由此可见,demo + 0 当然也应该指向第一个条目,而获取数组中条目地址的另一种方法是使用操作数地址&amp;,即&amp;demo[0]。所以demo 等于demo + 0 等于&amp;demo[0]

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

现在将上面的0 索引替换为1,得到的结果与您观察到的完全相同。

【讨论】:

【解决方案3】:
                        +-------+------+
                        |       |      |
                        |   13  |  45  |
                   101  |       |      | 105
                        +--------------+
                        |       |      |
                        |   83  |  34  |
                   109  |       |      | 113 
                        +--------------+
                        |       |      |
                        |   04  |  08  |
                   117  |       |      | 121 
                        +--------------+
                        |       |      |
                        |   234 | 934  |
                   125  |       |      | 129 
                        +--------------+

注意:假设sizeof(int) = 4

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

demo[i] 是二维数组的ith 行。它们本身就是一维数组。 demo[1]1th 行。 [我的意思是地址为109的那个]。

&demo[1] 

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

demo[1] 

由于数组名也给出了数组的基地址,所以它与&amp;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) 表示该位置的值。这本身就是一个数组,所以它给出了地址。因为数组名给出了地址

【讨论】:

  • 我不知道其余的答案,但我仍在寻找漂亮的 ASCII 艺术!!
  • @Rüppell'sVulture 我们都需要一点help ;) :D 我用过this
  • 人们是怎么做的?手动的?肯定需要很多时间和精力吧?或者有可用的工具吗?
猜你喜欢
  • 1970-01-01
  • 2020-11-28
  • 1970-01-01
  • 2013-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多