多维数组指针在C语言中的工作原理

多维数组指针在C语言中的工作原理,c,pointers,multidimensional-array,C,Pointers,Multidimensional Array,我正在试验C中多维数组指针的概念。假设我想通过函数处理多维数组。代码有点像这样: #include <stdio.h> void proc_arr(int ***array) { // some code } int main(int argc, char **argv) { int array[10][10]; for(int i = 0; i < 10; i++) { for(int j = 0; j < 10; j

我正在试验C中多维数组指针的概念。假设我想通过函数处理多维数组。代码有点像这样:

#include <stdio.h>

void proc_arr(int ***array)
{
    // some code
}

int main(int argc, char **argv)
{
    int array[10][10];
    for(int i = 0; i < 10; i++)
    {
        for(int j = 0; j < 10; j++)
        {
            array[i][j] = i * j;
        }
    }

    proc_arr(&array);

    return 0;
}
因此,我取消引用
数组
,告诉编译器我要转到该地址并获取值。但不知怎的,它崩溃了。我尝试了几种
*
和括号的组合,但仍然无法实现。我很确定这是因为我不理解指针和指针的指针

哦,我注意到,如果我们也使用
char**
(字符串数组)的话,情况就不同了,比如argv和envp。但是对于envp,我可以通过
(*envp)
访问它。为什么?

以下是处理envp(并起作用)的函数:

另外,我是否可以仅使用
envp
访问
envpn
函数中的
envp
,但仍然通过引用传递它


之前谢谢。

问题在于堆栈上分配的
int-array[10][10]
并没有按照您认为的方式布置内存。这是因为数组不是指针。内存仍然以线性数组的形式排列,而不是“二维”数组,尽管下标可能表示这一点。换句话说,
int数组[10][10]
的内存如下所示:

starting address:                                    ending address:
| Block_1 of 10 int | Block_2 of 10 int | ... | Block_10 of 10 int |
int*** array
|
|
| Pointer |
|
|
| Pointer_0 | Pointer_1 | ... | Pointer 10 |
       |          |                 |
       |          |                 | Block of 10 int |
       |          |
       |          | Block of 10 int |
       |
       |Block of 10 int|
因此,当您隐式地将数组转换为
int***
,然后尝试访问类似(*array)[1][10]的数组时,这实际上转化为类似
*(*((*array)+1)+10)
,并且这种操作的内存布局希望看到如下所示的内存设置:

starting address:                                    ending address:
| Block_1 of 10 int | Block_2 of 10 int | ... | Block_10 of 10 int |
int*** array
|
|
| Pointer |
|
|
| Pointer_0 | Pointer_1 | ... | Pointer 10 |
       |          |                 |
       |          |                 | Block of 10 int |
       |          |
       |          | Block of 10 int |
       |
       |Block of 10 int|
这行不通:

void proc_arr(int ***array)
{
    (*array)[0][1] = 10;
}

因为,在幕后,编译器必须将其更改为相对于数组开头的内存偏移量。这意味着它需要知道数组的维度。您尚未在函数签名中声明这些属性。

您的类型不匹配。给定声明
int-array[10][10]
,表达式
&array
的类型将是
int(*)[10][10]
不是
int***
。如果将函数原型更改为

void proc_arr(int (*array)[10][10])
那么您的代码应该可以像编写的那样工作

下表显示了给定特定声明的各种数组表达式的类型

Declaration: T a[M]; Expression Type Decays To ---------- ---- --------- a T [M] T * &a T (*)[M] *a T a[i] T Declaration: T a[M][N]; Expression Type Decays To ---------- ---- --------- a T [M][N] T (*)[N] &a T(*)[M][N] *a T [N] T * a[i] T [N] T * &a[i] T (*)[N] *a[i] T a[i][j] T Declaration: T a[M][N][O]; Expression Type Decays To ---------- ---- --------- a T [M][N][O] T (*)[N][O] &a T (*)[M][N][O] *a T [N][O] T (*)[O] a[i] T [N][O] T (*)[O] &a[i] T (*)[N][O] *a[i] T [N] T * a[i][j] T [N] T * &a[i][j] T (*)[N] *a[i][j] T a[i][j][k] T 声明:T a[M]; 表达式类型衰减为 ---------- ---- --------- a T[M]T* &a T(*)[M] *T a[i]T 声明:T a[M][N]; 表达式类型衰减为 ---------- ---- --------- a T[M][N]T(*)[N] &a T(*)[M][N] *T[N]T* a[i]T[N]T* &a[i]T(*)N] *a[i]T a[i][j]T 声明:T a[M][N][O];; 表达式类型衰减为 ---------- ---- --------- a T[M][N][O]T(*)[N][O] &a T(*)[M][N][O] *a T[N][O]T(*)[O] a[i]T[N][O]T(*)[O] &a[i]T(*)[N][O] *a[i]T[N]T* a[i][j]T[N]T* &a[i][j]T(*)[N] *a[i][j]T a[i][j][k]T
高维阵列的模式应该清晰

好的,我想我明白了:数组不是指针。谢谢