【问题标题】:Indirection Operator and Pointers to Array间接运算符和指向数组的指针
【发布时间】:2011-10-21 01:14:15
【问题描述】:

似乎间接运算符的常规定义在用于多维数组时不适用:

int arr[10][10][10];

如果你取消引用 arr,你会得到相同的地址:

(void*)arr == (void*)*arr && (void*)*arr == (void*)**arr

这是有道理的——多维数组只是一个连续的内存区域,指针指向内存的开头。编译器基本上忽略了取消引用,只是计算了正确的偏移量。使用间接运算符似乎只保留了多维数组的抽象,并使其与语言的其他句法结构相匹配。

如果您执行以下操作:

int *** ptr = (int***) arr;

然后取消引用 ptr,您将看到正常的取消引用行为,其中返回指针指定位置的值。使用上面的转换,如果你取消引用指针两次以上,你将读入未定义的内存。

我只是想知道为什么没有在更多地方记录这种行为 - 也就是说,间接运算符对指向数组的指针与指向指针的指针和指向值的指针的效果差异?

【问题讨论】:

  • 数组不是指针,尽管在某些情况下数组会转换为指针stackoverflow.com/questions/7844049。但是,数组永远不会变成高阶指针。这是数组->指针衰减规则的结果。 Array->pointer decay 是 C 语言中的一种,如果你知道发生了什么就很方便,如果你不知道,那就完全是巫术。

标签: c++ c pointers multidimensional-array


【解决方案1】:

首先,要完全理解这一点,您必须明白 C 没有多维数组——它有数组的数组。因此,在您的示例中,arr“由 10 个数组组成的数组,由 10 个 10 个整数组成的数组组成”

其次,行为不同的不是间接运算符,而是数组类型的表达式的行为很奇怪。

如果具有数组类型的表达式不是一元 &sizeof 运算符的主题1,则它的计算结果为指向第一个该数组的元素。

这意味着在以下表达式中:

(void*)*arr == (void*)**arr

在左侧,arr 计算为指向arr 内的第一个数组的指针,该数组包含 10 个 10 个整数数组(即 &arr[0])。然后取消引用以获取该数组本身:arr 中的第一个子数组arr[0]。然而,由于arr[0] 本身就是一个数组,所以它被替换为一个指向它的第一个元素的指针,&arr[0][0]

在右侧,上述情况按照左侧发生,然后取消引用最后一个指针,获得arr[0][0]。这又是一个数组,所以它最终被一个指向它的第一个元素的指针替换,&arr[0][0][0]

它们相等的原因(转换为void * 后)仅仅是因为数组arr[0][0] 的地址和int 的地址arr[0][0][0] 重合,因为后者是前者的第一个成员。他们还同意arr[0]arr的地址,所以你也有:

(void *)&arr == (void *)arr;
(void *)arr == (void *)*arr;

也是。


1。 ..and 不是初始化程序中使用的字符串文字。

【讨论】:

    猜你喜欢
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多