使用指针访问二维数组的元素

Accessing elements of 2D array using pointers

我正在阅读有关使用指针访问二维数组的各个元素的文章。

它建议使用以下机制来访问二维数组 arr[5][5] 的第 ith 行的第 jth 元素:

*(*(arr+i)+j)

根据我对指针的粗略理解,我了解到数组的名称产生第0个元素的第0个元素的地址th 行,数组的任何整数增量都将产生下一行的基地址。我想到现在为止一切都很好。

但是,我不明白的是以下代码段中间接 (*) 运算符的相关性:

*(arr+i)

这种情况下的间接运算符有何相关性?由于数组名称本身产生第 0th 行的基地址,因此向其添加任何整数都需要它指向下一行的基元素。在这种情况下,以下代码片段会生成第 ith 行的地址:

(arr+i)

并且添加 j 保证指针指向所述行的第 jth 个元素。

但是,在以下代码段中:

*(arr+i)

添加间接运算符不会导致它产生行的第 ith 元素,而不是 i[= 的基元素的地址第 48=] 行?

下面的代码不应该是访问第 ith 行的第 jth 元素的代码吗?

*((arr+i)+j)

在上述情况下,递增 arr i 次将使代码片段 (arr+i) 指向第 ith 行的基地址,然后添加of j 将包含第 ith 行的第 jth 元素的地址,然后间接运算符 (*) 将产生特定的元素地址保留,不是吗?

我的推理是否令人满意?

应该使用

访问ith/jth元素
arr[i][j]

但如果出于某种原因你不得不以艰难的方式去做,那就是

*((type *)arr + i * 5 + j)

其中 5 是数组中的列数。

的问题
*((arr+i)+j)

是 arr 类型错误,事情崩溃了。从理论上讲,以下应该有效,但我从未尝试过类似的方法:

*((type *)(arr+i)+j)

但从这里我们可以讨论

*(*(arr+i)+j)

再次;我从来没有尝试过这个;只是顶部的矩形形式。但是我们应该能够理解这一点。 arr 的类型是 type[][] 可以转换为 type[]*;因此 *(arr + i) 的结果应该是类型为 type[] 的第 i 行,它可以转换为 type*;因此我们应该期望 *(*(arr+i)+j) 访问第 j 列的第 i 行。如果没有内在的尊重,我们最终会得到第 (i+j) 行。

注意 arr 必须正确声明,否则它将把它解释为指向指针的指针而不是指向数组的指针,然后做错事。

From my cursory understanding of pointers, I am given to understand that the name of the array yields the address of the 0th element of the 0th row, and that any integral increment to the array will yield the base address of the next row. All's fine till this juncture, I suppose.

不是你想的那样。

表达式中使用的数组指示符被隐式转换(极少数例外)为指向其第一个元素的指针。

如果你有一个二维数组,例如

T arr[M][N];

(其中 T 是某种类型说明符)然后数组指示符 arr 被转换为指向数组第一个元素的 T ( * )[N] 类型的指针arr[0] 类型为 T[N].

当然指针的值等于T.

类型的第一个元素arr[0][0]的地址值

那么让我们考虑一下表达式

*(*(arr+i)+j)

在此表达式中,数组指示符 arr 被转换为指向数组第一个元素的指针。即表达式 arr 产生表达式 &arr[0] 的值。表达式 arr + i 产生值 &arr[i]。取消引用像 *( arr + i ) 这样的表达式,您将得到一维数组 arr[i] ,该数组又在表达式 *( arr + i ) + j 中使用,被转换为指向其第一个 T * 类型元素的指针等同于表达式 &arr[i][0] 。由于添加了变量 j,指针指向元素 &arr[i][j]。像

这样取消引用这个表达式
*(*(arr+i)+j)

相当于表达式 &arr[i][j] 你将得到元素 arr[i][j].

*((arr+i)+j)

(arr+i) 周围的括号在数学上是不必要的,但它们不足以将维度从行切换到元素。 i 用于行,j 用于元素,将它们分组是个好主意,但需要 *(...).

*(arr + i + j) 显然 ij 处于同一水平。