【问题标题】:Two dimension array dereferencing not working二维数组取消引用不起作用
【发布时间】:2021-11-18 16:45:05
【问题描述】:

您好,我正在学校学习 c,对这个问题有点困惑。
也就是说,
b 是两个 d 数组,我正在尝试围绕打印值和地址来实现,
但是为什么*(b+1) 给出的东西和b+1 一样呢?
我以为*(b+1) 会给出第二行第一个元素的值。
如果我将printf("%p\n", *(b+1)) 更改为printf("%d\n", *(b+1)),它只会给出一个垃圾值。

为什么会这样?

我感谢任何反馈!谢谢

int main()
{
    int b[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};

    printf("b:\n");
    print_2d_array(3, 4, b);
    printf("\n");
    
    printf("%p\n", b);
    printf("%p\n", *(b+1));
    printf("%p\n", b+1);
    
    return 0;
}

输出是这样的,

b:
  0   1   2   3 
  4   5   6   7 
  8   9  10  11 


0x7ffeecee6730
0x7ffeecee6740
0x7ffeecee6740

【问题讨论】:

  • 二维数组是数组的数组。所以取消引用它会得到嵌套数组之一。

标签: arrays c pointers


【解决方案1】:

您提出的问题基本上归结为一个关于数组性质和数组地址的问题,这是一个相当广泛的话题(例如,参见this)。但是,您可能对指针算法感到困惑,所以这个答案试图澄清其中的一些。

在 C 语言中,当在表达式中使用数组对象时,其值和类型与指向其第一个元素的指针相同。

在你的情况下,你有:

int b[3][4] = { /* ... */ };

/* ... */

printf("%p\n", *(b+1));
printf("%p\n", b+1);

如果我们考虑最后一个打印语句,表达式b + 1 中的b&b[0] + 1 相同,这将与&b[1] 相同。

当我们考虑最后一个之前的打印语句时,我们注意到*(b+1) 被定义为值b[1]。但是,该表达式的结果是一个包含 4 个int 的数组。该数组现在采用其第一个元素的值和类型,即&b[1][0]

由于您需要能够从数组本身中找到数组的第一个元素的地址,因此数组的地址&b[1]与其第一个元素的地址&b[1][0]具有相同的指针值.

但是,&b[1]&b[1][0] 具有不同的类型。前者是指向数组的指针,而后者是指向int的指针。

有关更多信息,我鼓励您阅读此答案顶部的链接问题,以了解有关数组和数组地址的更多信息。

【讨论】:

    【解决方案2】:

    *为什么 (b+1) 给出与 b+1 相同的东西?

    输出地址数值相同,但类型不同。

    *(b+1) 的类型是int [4],而b+1 的类型是int (*)[4]

    *(b+1),在表达式中使用时,将转换为第二行第一个元素的地址1)

    *(b + 1) -> b[1] -> ((b[1]) + (0)) -> &(*((b[1]) + (0))) -> &b[1][0]
    

    b+1 会给出第二行的地址。

    数组的地址和该数组的第一个元素的地址在数值上相同,但它们的类型不同。

    *我以为(b+1) 会给出第二行第一个元素的值。

    *(b+1) 将给出二维数组 b 的第二个元素,它只不过是一个由 4 整数组成的 1D 数组。

    要使用*(b+1) 访问第二行的第一个元素,您可以:

    (*(b+1))[0]
    

    要使用*(b+1) 访问第二行的第二个元素,您可以:

    (*(b+1))[1]
    

    第三个元素 ....

    (*(b+1))[2]
    

    等等.....

    注意*(b+1) 等同于b[1]1)。所以,

    (*(b+1))[0] is equivalent to b[1][0]
    (*(b+1))[1] is equivalent to b[1][1] .. and so on
    

    希望这能澄清您的疑问。


    1) 来自 C 标准#6.5.2.1

    下标运算符[]的定义是E1[E2]等同于(*((E1)+(E2)))..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-13
      • 2021-09-07
      • 2018-09-25
      • 2015-09-30
      • 1970-01-01
      • 1970-01-01
      • 2021-03-27
      相关资源
      最近更新 更多