首页 > 解决方案 > 在多维数组引用期间,解引用运算符告诉编译器做什么?

问题描述

我一直在玩多维数组和括号表示法,尽我所能对解引用、指针类型和指针算术之间的相互作用提出概念上的理解。

对于这个问题,请考虑以下任意 3D 数组引用:

    arr[i][j][k]

现在,我相信以下转换是等效的(我运行了一些我认为可以确认准确性的代码示例):

    *(*(*(arr+i)+j)+k)

我运行的代码如下所示:

#include <stdio.h>

int main(void) {

    char arr[2][3][4] = { 'a', 'b' ,'c' ,'d' ,'e' ,'f' ,'g' ,'h' ,'i' ,'j' ,'k' ,'l' ,'m' ,'n' ,'o' ,'p' ,'q' ,'r' ,'s' ,'t' ,'u' ,'v' ,'w' ,'x' };

    printf("%c \n", arr[1][1][1]);

    printf("%c \n", *(*(*(arr+1)+1)+1));

    return 0;
}

您可以更改printf语句中的值(只要ij和的值k在两者之间相同)。无论如何,他们总是同意将什么字母打印到命令终端。

我获得这个假定的等效答案的方式如下图所示(对不起,我使用了数学堆栈交换编写软件,因为它使一切变得更容易......如果指针算术的符号有点混乱,我很抱歉.)


推导


所以我的主要困惑来自取消引用运算符*。坦率地说,我不明白它告诉编译器做什么

举个简单的例子,假设字符数组arr从基地址 100 开始。

arr实际上是一个指向类型为 2D 矩阵的指针char[3][4]。我相信这意味着(因为一个字符需要 1 个字节)代码arr + 1实际上是在说100+12. 重写我的方程,然后我会:

*(*(*(112)+1)+1). 我相当确定取消引用运算符(在 的左侧112)从左到右优先于+符号(在 的右侧112)。

根据我在 1D 情况下使用取消引用符号的经验,这将产生存储在 112 存储单元中的值。但这在目前的情况下似乎是错误的。显然,我不了解取消引用操作在这种情况下的行为方式。任何帮助是极大的赞赏!

干杯~

标签: arrayscpointers

解决方案


您需要了解两点:

  • 数组不是指针,即使在大多数情况下它们会自动转换为指针。

  • 与一维数组相比,多维数组得到零特殊处理。它们一维数组,其中每个元素也是一个数组。


当您这样做时*(*(*(arr+1)+1)+1)arr会自动转换为指向其第一个元素的指针。该指针具有类型char(*)[3][4](指向 的指针char[3][4])。添加1它会使指针的值增加1*sizeof(char[3][4]) == 12. 你似乎已经知道这一点。

取消引用生成的指针会给你一个类型的左值char[3][4]然后它会衰减为类型char(*)[4]等于的指针&arr[1][0]。添加1到该指针会使它增加1*sizeof(char[4]),之后它等于&arr[1][1]

取消引用结果指针会为您提供 type 的左值char[4]。它还衰减为类型char *等于的指针&arr[1][1][0]。添加1到它之后,它的值增加1*sizeof(char)并变为等于&arr[1][1][1]。然后最后的取消引用给你的值arr[1][1][1]


推荐阅读