为什么我们需要使用双指针来访问二维数组?
Why do we need to use double pointer to access a 2-D array?
我试图理解多维数组和指针,写了这个小程序来理解这个概念:
#include<stdio.h>
void show(int arr[][2]);
int main()
{
int z[2][2] = { { 1, 2 },
{3, 4 } };
show(z);
}
void show(int arr[][2])
{
printf("value of arr = %d", arr);
printf("\n\nvalue of &arr[0]0] = %d", &arr[0][0]);
}
此代码片段打印出相同的地址,这是有道理的,但是当我编辑显示函数时:
void show(int arr[][2])
{
printf("value of *arr = %d", *arr);
printf("\n\nvalue of arr[0]0] = %d", arr[0][0]);
}
*arr 仍然打印相同的地址,而 arr[0][0] 按预期打印整数值,我想知道为什么我需要使用 **arr 来获取 int 值,如果 arr 正在存储它应该用 *arr 取消引用的地址,不是吗?
请帮助我真的很难理解这个概念..在此先感谢。
如果你看一下二维数组的内存布局,事情可能会变得更清楚一些。
您将变量定义为:
int z[2][2] = {{1, 2}, {3, 4}};
内存:
z
|
v
+-----+-----+-----+-----+
| 1 | 2 | 3 | 4 |
+-----+-----+-----+-----+
内存的另一种看法:
z[0] z[1]
| |
v v
+-----+-----+-----+-----+
| 1 | 2 | 3 | 4 |
+-----+-----+-----+-----+
内存的另一种看法:
z[0][0] z[1][0]
| z[0][1] | z[1][1]
| | | |
v v v v
+-----+-----+-----+-----+
| 1 | 2 | 3 | 4 |
+-----+-----+-----+-----+
你现在可以看到,就纯内存位置而言,
&z == &z[0] == &z[0][0]
我们还知道,当数组衰减为指针时,其值是数组第一个元素的地址。因此,当用于将 z
衰减为指针的表达式时,
z == &z[0] == &z (from above)
这很令人费解,但是 z
和 &z
计算出相同的地址,即使它们是不同的类型。
z 衰减为指针时的类型是 int (*)[2]
。 &z
的类型是 int (*)[2][2]
.
参加你的活动,你有:
void show(int arr[][2]) { ... }
相当于:
void show(int (*arr)[2]) { ... }
为什么 arr
和 *arr
的计算结果相同?
arr
从 main
求得 &z[0]
。
*arr
从 main
求得 z[0]
,从 main.
求得 &z[0][0]
我们已经看到&z[0]
和&z[0][0]
的值是一样的。因此 show()
中的 arr
和 *arr
计算出相同的地址。
我试图理解多维数组和指针,写了这个小程序来理解这个概念:
#include<stdio.h>
void show(int arr[][2]);
int main()
{
int z[2][2] = { { 1, 2 },
{3, 4 } };
show(z);
}
void show(int arr[][2])
{
printf("value of arr = %d", arr);
printf("\n\nvalue of &arr[0]0] = %d", &arr[0][0]);
}
此代码片段打印出相同的地址,这是有道理的,但是当我编辑显示函数时:
void show(int arr[][2])
{
printf("value of *arr = %d", *arr);
printf("\n\nvalue of arr[0]0] = %d", arr[0][0]);
}
*arr 仍然打印相同的地址,而 arr[0][0] 按预期打印整数值,我想知道为什么我需要使用 **arr 来获取 int 值,如果 arr 正在存储它应该用 *arr 取消引用的地址,不是吗?
请帮助我真的很难理解这个概念..在此先感谢。
如果你看一下二维数组的内存布局,事情可能会变得更清楚一些。
您将变量定义为:
int z[2][2] = {{1, 2}, {3, 4}};
内存:
z
|
v
+-----+-----+-----+-----+
| 1 | 2 | 3 | 4 |
+-----+-----+-----+-----+
内存的另一种看法:
z[0] z[1]
| |
v v
+-----+-----+-----+-----+
| 1 | 2 | 3 | 4 |
+-----+-----+-----+-----+
内存的另一种看法:
z[0][0] z[1][0]
| z[0][1] | z[1][1]
| | | |
v v v v
+-----+-----+-----+-----+
| 1 | 2 | 3 | 4 |
+-----+-----+-----+-----+
你现在可以看到,就纯内存位置而言,
&z == &z[0] == &z[0][0]
我们还知道,当数组衰减为指针时,其值是数组第一个元素的地址。因此,当用于将 z
衰减为指针的表达式时,
z == &z[0] == &z (from above)
这很令人费解,但是 z
和 &z
计算出相同的地址,即使它们是不同的类型。
z 衰减为指针时的类型是 int (*)[2]
。 &z
的类型是 int (*)[2][2]
.
参加你的活动,你有:
void show(int arr[][2]) { ... }
相当于:
void show(int (*arr)[2]) { ... }
为什么 arr
和 *arr
的计算结果相同?
arr
从 main
求得 &z[0]
。
*arr
从 main
求得 z[0]
,从 main.
&z[0][0]
我们已经看到&z[0]
和&z[0][0]
的值是一样的。因此 show()
中的 arr
和 *arr
计算出相同的地址。