间接运算符和数组指针

发布于 2024-12-10 20:08:19 字数 536 浏览 0 评论 0原文

当间接寻址运算符用于多维数组时,它的常规定义似乎并不适用:

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

如果您取消引用 arr,您将获得相同的地址:

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

但这很有意义 - 多维数组只是一个连续的数组内存区域,指针指向内存的开头。编译器本质上会忽略取消引用,只计算正确的偏移量。使用间接运算符似乎只保留了多维数组的抽象,并使其适合该语言的其他语法结构。

如果执行以下操作:

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

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

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

It seems the regular definition of the indirection operator doesn't apply when it is used on multi-dimensional arrays:

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

If you dereference arr, you'll get the same address:

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

This makes sense though - a multi-dimensional array is just a contiguous region of memory, where the pointer points at the beginning of the memory. The compiler essentially ignores dereferences and just computes the proper offset. Use of the indirection operator seems to only preserve the abstraction of multi-dimensional arrays and make it fit with the other syntactic constructs of the language.

If you do the following:

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

And dereference ptr, you'll see the normal dereference behavior, where the value in the location specified by the pointer is returned. Using the above cast, you'll read into undefined memory if you dereference the pointer more than twice.

I'm just wondering why this behavior isn't documented in more places - that is, the difference of effect of the indirection operator on pointers to arrays vs pointers to pointers and pointers to values?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一个人的旅程 2024-12-17 20:08:19

首先,要完全理解这一点,您必须认识到 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 is not a string literal used in an initializer.

Firstly, to fully understand this you must appreciate that C does not have multidimensional arrays - it has arrays of arrays. So, in your example, arr is "an array of 10 arrays of 10 arrays of 10 ints".

Secondly, it's not the indirection operator that behaves differently, it's the behaviour of expressions with array type that's odd.

If an expression with array type is not the subject of either the unary & or sizeof operators1, then it evaluates to a pointer to the first element of that array.

This means that in the following expression:

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

On the left hand side, arr evaluates to a pointer to the first array of 10 arrays of 10 ints within arr (that is, &arr[0]). This is then dereferenced to obtain that array itself: the first sub-array within arr, arr[0]. However, since arr[0] is itself an array, this then is replaced with a pointer to it's first element, &arr[0][0].

On the right hand side, the above happens as per the left hand side, then that last pointer is dereferenced, obtaining arr[0][0]. This, again, is an array, so it is finally replaced with a pointer to its first element, &arr[0][0][0].

The reason these are equal (after conversion to void *) is simply because the address of the array arr[0][0] and the address of the int arr[0][0][0] coincide, as the latter is the first member of the former. They also concide with the address of arr[0] and arr, so you also have:

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

as well.


1. ..and is not a string literal used in an initializer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文