多维数组指针如何在C语言中工作



我正在实验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;
}

问题是,当我想在proc_arr中访问array时,我不能。根据我的理解,我们应该这样访问它:

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

所以我解引用array来告诉编译器我想去那个地址并获得值。但不知何故,它崩溃了。我已经尝试了*和括号的几种组合,仍然不能使它工作。我很确定这是因为我不理解指针和指针的指针。

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

下面是处理envp的函数:

int envplen(char ***envp)
{
    int count = 0;
    while((*envp)[count] != NULL)
    {
        count++;
    }
    return count;
}

此外,我能否以某种方式访问envplen函数中的envp,只有envp,但仍然通过引用传递它?

谢谢。

这个问题是因为在堆栈上分配的int array[10][10]并不像您想象的那样布局内存。因为数组不是指针。内存仍然以线性数组的形式排列,而不是"二维"数组,尽管下标可能表明了这一点。换句话说,int array[10][10]的内存如下所示:

starting address:                                    ending address:
| Block_1 of 10 int | Block_2 of 10 int | ... | Block_10 of 10 int |

所以当你隐式地将数组转换为int***,然后尝试访问像(*array)[1][10]这样的数组时,它实际上转换为类似*(*((*array) + 1) + 10)的东西,并且这种操作的内存布局希望看到像下面这样的内存设置:

int*** array
|
|
| Pointer |
|
|
| Pointer_0 | Pointer_1 | ... | Pointer 10 |
       |          |                 |
       |          |                 | Block of 10 int |
       |          |
       |          | Block of 10 int |
       |
       |Block of 10 int|

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

void proc_arr(int (*array)[10][10])

那么你的代码应该可以正常工作。

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

<>之前声明:T a[M];表达式类型衰减为---------- ---- ---------a T [M] T *& T (*)[M]* T[我]T申报:T a[M][N];表达式类型衰减为---------- ---- ---------T [M][N] T (*)[N]和T (*) [M] . [N]*a T [N] T *a[i] T [N] T *&a[i] T (*)[N]* T[我]一个T[我][j]申报: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]* T[我][j][我][j] [k] T之前

高维数组的模式应该是清晰的。

这行不通:

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

因为,在幕后,编译器必须将其转换为相对于数组开始的内存偏移量。这意味着它需要知道数组的维数。您没有在函数签名中声明这些

相关内容

  • 没有找到相关文章

最新更新