使用[]运算符访问动态数组 让我们考虑下面的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]
achar数组[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]
,您试图强制它成为字符**
,但您不能,这就是警告告诉您的。第二个不是“动态声明的”,是将应该是指向指针的指针分配给指向指针数组的指针。另外,如果要动态分配多维数组,则必须指定其所有维度,但第一个维度除外。哦,好的,我找到了。也帮了忙。