ato*_*erz 7 c++ arrays pointers casting
我有以下来源:
#include <iostream>
using namespace std;
void main(int j)
{
char arr[10][10];
char** ptr;
ptr = arr;
}
Run Code Online (Sandbox Code Playgroud)
当我使用VS2010编译它时,我收到此错误:
error : a value of type "char (*)[10]" cannot be assigned to an entity of type "char **"
Run Code Online (Sandbox Code Playgroud)
我认为c ++中的数组只是指针.所以char[][]也可以char**.我究竟做错了什么?
Oli*_*rth 12
数组不是指针.
在大多数情况下,数组会衰减到指针,但这不是递归的.所以一个T[]衰变到一个T *,但一个T[][]不衰败到一个T**.
我建议阅读关于数组和指针的整个C FAQ 章节 ; 特别是关于2D数组和指针指针的部分.
现有的答案,虽然是正确的,不让它很清楚,有一个根本的原因(除了语言规则),为什么你不能投char [10][10]来char **.即使你强迫演员表达类似的东西
char arr[2][2];
char ** ptr = (char **)arr;
Run Code Online (Sandbox Code Playgroud)
它实际上不会起作用.
原因是在C和C++中,二维数组在内存中布局为数组数组.也就是说,在C中,二维数组作为单个分配布局在内存中,
arr -> arr[0][0]
arr[0][1]
arr[1][0]
arr[1][1]
Run Code Online (Sandbox Code Playgroud)
你会注意到arr它并不是指向a char *而是指向arr[0][0]a char; 因此,虽然arr可以投射到a char *,但它不能被投射到char **.
正确的强迫演员会是
char arr[2][2];
char * ptr = (char *)arr;
Run Code Online (Sandbox Code Playgroud)
如果你不想强制演员(如果可能的话,总是一个好主意!)你会说
char arr[2][2];
char * ptr = arr[0];
Run Code Online (Sandbox Code Playgroud)
或者,为了使结果更清楚,
char arr[2][2];
char * ptr = &arr[0][0];
Run Code Online (Sandbox Code Playgroud)
而且你现在(实际上)有一个指向4个字符数组的指针.[Proviso:我在C标准中找不到任何禁止实现在数组的两行之间添加填充的内容,但我不相信任何实际的实现都这样做,并且常见的编码实践取决于假设没有这样的填充.]
如果你真的需要转换arr为a,char **你必须显式创建一个指针数组:
char arr[2][2]
char * arr_ptrs[2];
char ** ptr;
arr_ptrs[0] = arr[0];
arr_ptrs[1] = arr[1];
ptr = arr_ptrs;
Run Code Online (Sandbox Code Playgroud)
如果你试图将二维数组转换为指针指针,C语言原则上可以自动执行此操作,但这会违反程序员对转换没有副作用(例如分配内存)的期望.
在Java中,通过比较,二维数组总是一个指向数组的指针数组,因此就是数组
char arr[][] = { {'a', 'b'}, {'c', 'd'} };
Run Code Online (Sandbox Code Playgroud)
在内存中作为三个单独的分配,按任意顺序排列,不一定相邻,
arr -> arr[0]
arr[1]
arr[0] -> arr[0][0]
arr[0][1]
arr[1] -> arr[1][0]
arr[1][1]
Run Code Online (Sandbox Code Playgroud)
您会立即注意到这需要比等效C数组更多的内存,并且在运行时评估的速度较慢.另一方面,它确实允许数组的行具有不同的长度.
类型char[10][10]和char**和char (*)[10]都是不同的类型。但是,第一个不能转换为第二个,它可以转换为第三个。
所以试试这个:
char arr[10][10];
char (*ptr)[10];
ptr = arr; //ok
Run Code Online (Sandbox Code Playgroud)
它会起作用,因为正如我所说的 object of typechar[10][10]可以转换为 type 的对象char (*)[10]。它们是兼容的类型。