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

标签 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++)
        {
            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;
}

此外,我能否仅使用 envpenvplen 函数中以某种方式访问​​ 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|

关于c - C语言中多维数组指针的工作原理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7161247/

相关文章:

c - 从/dev/random (c) 读取随机 double

c - 64 位系统差异上的数据填充

C 将指针传递给 char 的指针

python - 如何在Python中操作多维numpy数组

c# - 在C#中创建二维数组的数组

python - 什么时候 ndarray 的大小不固定?

c - 在c中评估Linux文件复制命令

c - 在分隔符处分割一行文本后打印

c - 表达式必须有指针类型错误

c - 意外错误 "control may reach end of a non void function"