当在多维数组上使用时,间接运算符的常规定义似乎不适用:
int arr[10][10][10];
如果您取消引用,您将获得相同的地址:
(void*)arr == (void*)*arr && (void*)*arr == (void*)**arr
这是有道理的 - 多维数组只是一个连续的内存区域,其中指针指向内存的开头。编译器基本上忽略了解引用并只计算了正确的偏移量。使用间接运算符似乎只保留了多维数组的抽象,并使其适合该语言的其他语法结构。
如果您执行以下操作:
int *** ptr = (int***) arr;
并且取消引用ptr,您将看到正常的取消引用行为,其中返回指针指定的位置中的值。使用上面的演员,如果你将指针取消引用两次以上,你将读入未定义的内存。
我只是想知道为什么在更多地方没有记录这种行为 - 也就是说,间接运算符对指针到数组的指针与指针指针和指向值的指针的影响差异?
答案 0 :(得分:1)
首先,要完全理解这一点,你必须明白C没有多维数组 - 它有数组数组。因此,在您的示例中,arr
是“10个10个数组的10个数组的数组的数组”。
其次,不是行为不同的间接运算符,它是数组类型奇怪的表达式的行为。
如果数组类型的表达式不是一元&
或sizeof
运算符 1 的主题,那么它将计算为a指向该数组的第一个元素的指针。
这意味着在以下表达式中:
(void*)*arr == (void*)**arr
在左侧,arr
计算指向arr
(即&arr[0]
)内10个10个整数数组的第一个数组的指针。然后取消引用以获取该数组本身: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。 ..并且不是初始值设定项中使用的字符串文字。