使用[]运算符访问动态数组 让我们考虑下面的C代码: char matrix[10][10]; char** array; array = matrix; printf("%c", array[2][3]);

使用[]运算符访问动态数组 让我们考虑下面的C代码: char matrix[10][10]; char** array; array = matrix; printf("%c", array[2][3]);,c,arrays,dynamic,C,Arrays,Dynamic,我在第array=matrix行有一条警告:来自不兼容指针类型的赋值 我猜这是因为第一个数组是静态声明的,第二个数组是动态声明的,但真正的问题在printf行。程序完全崩溃。 我似乎无法使用[]运算符访问字符**。 我怎样才能解决这个问题 注意:我稍微简化了上下文。在原始程序中,数组通过一个返回类型为char**的函数分配,但实际上返回一个char[10][10]achar数组[10][10]不会退化为char**,而是一个char*。多维数组在内存中是连续的,但char**是指向指针的指针,这

我在第
array=matrix
行有一条警告:
来自不兼容指针类型的赋值

我猜这是因为第一个数组是静态声明的,第二个数组是动态声明的,但真正的问题在
printf
行。程序完全崩溃。
我似乎无法使用
[]
运算符访问
字符**

我怎样才能解决这个问题


注意:我稍微简化了上下文。在原始程序中,
数组
通过一个返回类型为
char**
的函数分配,但实际上返回一个
char[10][10]
a
char数组[10][10]
不会退化为
char**
,而是一个
char*
。多维数组在内存中是连续的,但
char**
是指向指针的指针,这意味着不能保证每个“行”在内存中彼此相邻

Ie
数组[10][10]
在内存中看起来像这样

&array (type char*)
|
| (points to)
|
\/
|---row/array one of length 10 chars---|---row/array two of length 10 chars---|...|---row/array ten of length 10 chars---|
这其实和

&array (type char*)
|
| (points to)
|
\/
|---array of length 100 chars---|
因此,它或多或少类似于
char[100]
,只是访问方式不同而已

另一方面,
char**p2p
的工作原理如下

p2p (type char **) (points to array of pointers which is contiguous in memory) 
|
| (points to)
|
\/
|---pointer to first row of chars---|---pointer to second row of chars---|...
                 |                                    |
                 | (points to)                        |  (points to)
                 |                                    |
                 \/                                   \/
|****************|--row/array of chars--|*************|-- row/array of chars--|********

其中,
***
是未知大小的任意内存位。事实上,不能保证最后一组数组是按任何特定顺序排列的,更不用说它们彼此相邻(即最后一组箭头可能相互“交叉”)。

如果需要指向角色数组的指针,则可以创建一个指针并将其指向需要访问的行,如下图所示

   int main()
    {
    char matrix[10][10];
    char* array;

    matrix[2][3] = 'c';
    array= matrix[2];
    printf("%c", array[3]);
    return 0;
    }

char**
char[10][10]
不同。与
char[N][N]
的存储方式相比,当我们展示
char**
如何存储在内存中时,可能最容易解释这个问题

例如,假设一个
char[3][3]
数组初始化如下:

char matrix[3][3];
int count = 0;
for(int i = 0; i < 3; ++i)
{
    for(int j = 0; j < 3; ++j)
    {
        matrix[i][j] = count++;
    }
}
char矩阵[3][3];
整数计数=0;
对于(int i=0;i<3;++i)
{
对于(int j=0;j<3;++j)
{
矩阵[i][j]=count++;
}
}
这将在内存中显示如下内容:

char matrix[3][3];
int count = 0;
for(int i = 0; i < 3; ++i)
{
    for(int j = 0; j < 3; ++j)
    {
        matrix[i][j] = count++;
    }
}
0123456789

请注意,元素在内存中顺序排列,没有指针

变量
matrix
也可以解释为指向数组中第一个元素的
char[3]*

取消引用一个
char[3]*
返回一个
char[3]
数组,该数组又可以被另一个
[]
操作符取消引用。因此
矩阵的元素0可以被认为是数组
[0,1,2]
。我们可以使用另一个
[]
操作符取消引用该数组的特定元素


另一方面,
char**
在取消引用时返回一个
char*
。访问
char**
的特定元素会得到一个
char*
。在上面的示例中,访问数组矩阵的元素0返回值0。然后将其视为
char*
并使用另一个
[]
运算符要解除引用,它将尝试访问内存位置0+某个偏移量处的
字符。
这几乎肯定会导致segfault。

“我似乎无法使用[][]运算符访问字符**。你的理论是错误的。你一开始就没有
字符**
。你有一个
字符[10][10]
,您试图强制它成为
字符**
,但您不能,这就是警告告诉您的。第二个不是“动态声明的”,是将应该是指向指针的
指针分配给指向指针数组的
指针。另外,如果要动态分配多维数组,则必须指定其所有维度,但第一个维度除外。哦,好的,我找到了。也帮了忙。