【问题标题】:cannot understand addressing in 2d array in c无法理解 c 中二维数组中的寻址
【发布时间】:2012-08-22 13:52:25
【问题描述】:
main()
{
    int a[3][2] = { {1,2},{3,4},{5,6}};
    for(int i=0;i<3;i++)
        for(int j=0;j<2;j++)
    {
        printf("%d", a[i][j]);
        printf("\t %d\n", &a[i][j]);
    }
    printf("\n%d", *(a+1));
    printf("\n%d", *a+1);
}

*(a+1) 的输出与 *a+1 不同。

*(a+1) 指向第三个元素,而

*a+1 正在输出第二个值

【问题讨论】:

  • 请参阅 this question 以获得很好的解释。
  • 阅读comp.lang.c FAQ的第6节。
  • *(a+1) 正在为您打印第三个元素,因为在您的主机环境中,sizeof(int *) 似乎是 sizeof(int) 的两倍。 *a+1 仅打印第二个值,因为它实际上使用了第一个值(*a,即1)并向其添加1,这恰好产生了第二个值。
  • @veer:数组的每个元素都是int[2],而不是int*。因此,它增加了sizeof(int[2]),而不是sizeof(int*)
  • @veer int (*p)[2]; p = &a[0]; printf("%d\n", *(p+1)); printf("%d\n", (p+1));为什么这两个语句返回相同的值

标签: c arrays 2d


【解决方案1】:

*(a+1) 的输出与 *a+1 不同。

是的,由于operator precedence*a + 1 表示...

取消引用a(返回int)并向其添加1。返回结果(2

但是,*(a + 1) 说...

1 添加到指针 a 并取消引用它,即获取地址a + sizeof(int[2]) 处的值。

“值*”恰好是第二个数组的第一个元素。记住;将 n 添加到指针类型会使地址前移 n 个元素。在这种情况下,每个元素都是int 的数组,其中包含两个自己的元素。

这也应该回答接下来的两个问题。读完运算符优先级后,开始学习pointer arithmetic

【讨论】:

    【解决方案2】:

    C 并没有真正的多维数组,它有数组的数组。 int a[3][2] 声明了一个三元素数组,其元素是二维整数数组。

    指针的算术考虑了这一点,它增加了指针指向的对象的大小。所以(a+1) 计算为a 的第二个元素,它是指向数组{3, 4} 的指针。通过这个指针间接获得它的第一个元素,即 3。

    *a 另一方面,通过指向a 的第一个元素的指针进行间接寻址,其计算结果为 1。然后当您将 1 添加到此时,您得到 2。它实际上并没有返回第二个元素,它只是看起来像因为 1+1 = 2。尝试将初始化更改为:

    int a[3][2] = { {1,3},{5,7},{9,11}};
    

    你的输出将是 5 和 2。

    【讨论】:

    • C 确实有二维数组;标准这样称呼他们。它们恰好是数组的数组。
    • 如果您坚持数组索引语法并提供所有维度,它们就像任何其他语言的二维数组一样工作。但是,如果您想了解当您将它们视为指针时它们是如何工作的,或者在数组索引中省略维度时,您必须将它们视为数组的数组。
    • Ada,例如,区分二维数组和数组数组。前者索引为Arr[I, J],后者索引为Arr[I][J];两者不可互换。如您所知,C 的索引运算符是根据指针算术定义的。我不太清楚您所说的“当您将它们视为指针时”是什么意思。
    • OP 通过使用显式取消引用和算术而不是数组语法将它们视为指针。
    【解决方案3】:

    您应该阅读有关运算符优先级的信息。在第二种情况下,*a+1 一元运算符 * 比二元运算符 + 绑定更多。因此,该操作被视为将a 指向的值加一。

    在前一种情况*(a+1) 中,您正在寻址a 指向的下一个元素并取消引用它以获取其值。

    HTH。

    【讨论】:

      【解决方案4】:

      是的,没错。 因为一个二维数组代表一维数组的数组。在这种情况下 a[3][2] = { {1,2},{3,4},{5,6}},数组名称,即 a 充当数组的第零个元素。由于我们的二维数组的第 0 个元素是 2 个整数 {1,2} 的一维数组。因此,(a+1) 指的是二维数组{3,4} 的第一个元素的地址,因此 *(a+1) 给出了值在那个地址,即 3。而,*a 可以访问第一个元素,然后将其增加一个给 2。

      【讨论】:

        猜你喜欢
        • 2020-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-08
        • 1970-01-01
        相关资源
        最近更新 更多