C++ 自定义void函数打印二维字符数组出现报错
代码报错的根本原因
- 函数形参的数组声明写法不合法。C++语法不支持在二维数组的形参位置直接留空第二维的声明,也就是
char[][] matrix这种写法根本通不过编译:数组作为参数传递时会隐式退化为指向首元素的指针,二维数组的首元素是定长的一维数组,要计算任意matrix[i][j]的内存地址,编译器必须提前知道每一行的固定长度(即第二维的大小),否则根本算不出第i行对应的内存起始位置,直接触发语法报错。 - 主函数内的
char mat[n][m]属于GCC、Clang等编译器扩展支持的变长数组(VLA),不属于标准C++规范。只是因为这个数组是在main函数的当前作用域定义的,编译器能直接拿到这个作用域下的行列尺寸信息,两层for循环直接遍历的时候内存计算逻辑是自洽的,所以可以正常运行;但一旦把数组作为参数传递到其他函数,配合本身就不合法的形参写法,就会直接编译失败。
可正常运行的修正写法参考
- 固定维度匹配写法:如果数组的列数固定为4,形参必须明确写出第二维的大小,把函数定义改成:
void printt(int x, int y, char matrix[][4]) { for(int i = 0; i< x; i++){ for(int j = 0; j<y; j++){ std::cout<<matrix[i][j]; } } } - 标准C++兼容写法:把数组的行列尺寸改成编译期常量,避免使用非标准的变长数组定义,也就是把main函数里的变量定义换成:
这种写法下,上面的固定维度形参就可以在所有合规C++编译器(包括MSVC)上正常运行。constexpr int n = 4, m = 4; char mat[n][m]; - 通用适配写法:如果不想把数组大小硬编码在形参里,可以把二维数组的首地址按一级指针传入,手动计算内存偏移:
调用的时候直接把数组名传入即可(数组名会自动退化为首元素的一级指针),不需要指定固定维度,适配任意行列尺寸的连续字符数组。void printt(int x, int y, char* matrix) { for(int i = 0; i< x; i++){ for(int j = 0; j<y; j++){ // 第i行第j个元素的内存偏移:i乘以每行的元素总数,再加列偏移j std::cout<< *(matrix + i*y + j); } } }
内容的提问来源于stack exchange,提问作者user15014634
相关产品推荐
相关产品推荐

