二维数组指针运算

use*_*929 0 c c++ arrays pointers

假设我有一个 int 数组:int arr[5][5]并假设 C 语言内存管理。

我想仅使用指针算术和取消引用来访问数组的特定元素。

假设我想访问以下元素: arr[i][j]

我一开始尝试打印一些内容来了解​​地址是如何工作的。arr我打印了、arr+1、 、arr+2、的地址arr+5

结果如下:

0x7fff58475b80
0x7fff58475b94
0x7fff58475ba8
0x7fff58475be4
Run Code Online (Sandbox Code Playgroud)

我想知道为什么每个地址之间的差异是 14(十六进制)或 20(十进制)。

另外,当您在堆栈上创建一个二维数组时,是否会创建一个指向内存块指针数组的指针?这就是我假设我们为数组分配空间的方式:

  1. 在堆栈上分配一个指针arr
  2. 指针arr保存指针数组起始位置的地址。
  3. 该指针数组包含二维数组中行的起始位置。

它是否正确?

编辑:另外,假设您想通过指针算术访问 arr[i][j] 。这将如何完成?如果数组是动态分配的,我认为你可以这样做 *( * (arr+i)+j)。我不确定你如何对静态分配执行此操作?我的猜测是 *(arr + ((row_size * (i))+j))。它是否正确?

Ale*_*exD 5

\n

我想知道为什么每个地址之间的差异是 14(十六进制)或 20(十进制)。

\n
\n\n

也许是因为在您的系统上, 的大小int是并且内部数组中4有整数。5

\n\n

要了解布局的想法,请尝试以下代码:

\n\n
int a[5][5];\nint k = 0;\nfor (int i = 0; i < 5; i++)\n    for (int j = 0; j < 5; j++)\n        a[i][j] = ++k;\nint* p = &a[0][0];\nfor (int n = 0; n < 25; n++, p++)\n    printf("%d ", *p);\n
Run Code Online (Sandbox Code Playgroud)\n\n

输出是

\n\n
1 2 3 4 ... 25\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

标准中有一条注释C++(在8.3.4 数组 [dcl.arrays]中):

\n\n
\n

[ 注意:由此可见,C++ 中的数组是按行存储的(最后一个下标变化最快),并且声明中的第一个下标有助于确定数组消耗的存储量,但不参与其他部分在下标计算中。\xe2\x80\x94结束注]

\n
\n