为什么我们需要使用双指针来访问二维数组呢?

mig*_*WOZ 1 c arrays pointers double-pointer multidimensional-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]);
}
Run Code Online (Sandbox Code Playgroud)

这个代码片段打印相同的地址是有意义的,但是当我编辑show函数时:

void show(int arr[][2])
{

    printf("value of *arr = %d", *arr);
    printf("\n\nvalue of arr[0]0] = %d", arr[0][0]);
}
Run Code Online (Sandbox Code Playgroud)

*arr仍然打印相同的地址,而arr [0] [0]按预期打印整数值,我想知道为什么我需要使用**arr来获取int值,如果arr存储它应该是的地址用*arr取消引用,不是吗?

请帮助我很难理解这个概念..提前感谢.

R S*_*ahu 5

如果你看一下2D数组的内存布局,事情可能会变得更加清晰.

您将变量定义为:

int z[2][2] = {{1, 2}, {3, 4}};
Run Code Online (Sandbox Code Playgroud)

记忆:

z
|
v
+-----+-----+-----+-----+
|  1  |  2  |  3  |  4  |
+-----+-----+-----+-----+
Run Code Online (Sandbox Code Playgroud)

另一种记忆观点:

z[0]        z[1]
|           |
v           v
+-----+-----+-----+-----+
|  1  |  2  |  3  |  4  |
+-----+-----+-----+-----+
Run Code Online (Sandbox Code Playgroud)

另一种记忆观点:

z[0][0]     z[1][0]
|   z[0][1] |    z[1][1]
|     |     |     |
v     v     v     v
+-----+-----+-----+-----+
|  1  |  2  |  3  |  4  |
+-----+-----+-----+-----+
Run Code Online (Sandbox Code Playgroud)

你现在可以看到,就纯内存位置而言,

&z == &z[0] == &z[0][0]
Run Code Online (Sandbox Code Playgroud)

我们也知道当数组衰减到指针时,它的值是数组的第一个元素的地址.因此,当在一个衰减z到指针的表达式中使用时,

z == &z[0] == &z (from above)
Run Code Online (Sandbox Code Playgroud)

它令人费解,但z&z计算出相同的地址,即使它们是不同的类型.

z衰减到指针时的类型是int (*)[2].类型&zint (*)[2][2].

来到你的功能,你有:

void show(int arr[][2]) { ... }
Run Code Online (Sandbox Code Playgroud)

这相当于:

void show(int (*arr)[2]) { ... }
Run Code Online (Sandbox Code Playgroud)

为什么arr*arr计算出相同的价值呢?

arr评估&z[0]来自main. *arr评估z[0]来自main,评估&z[0][0]来自main.

我们已经看到了&z[0]和的价值&z[0][0]相同.因此,arr*arrshow()计算出相同的地址.