最近在写一个顺时针打印矩阵的函数时,发现二维数组名不能传递给一个二级指针。
#include <iostream>
// 顺时针打印矩阵
void PrintMatrixClockWisely(int** numbers, int rows, int columns)
{
}
int main()
{
int matrix[3][4] = {
{1, 2, 3, 4},
{10, 11, 12, 5},
{9, 8, 7, 6}
};
PrintMatrixClockWisely(matrix, 3, 4);
return EXIT_SUCCESS;
}
编译时无法通过,提示:error: cannot convert 'int (*)[4]' to 'int**'
找到一篇文章讲了关于二级指针与二维数组的转换,很详细。自己也做个笔记。
https://www.cnblogs.com/rainySue/p/er-wei-shu-zu-he-er-ji-zhi-zhen.html
二维数组本质
一维数组名,数组首元素的地址,是一个指针。
二维数组也是内存中一块线性连续空间,因此在内存级别上,其实都只是一维。
// 可以将二维数组看成特殊的一级数组
int matrix[3][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12} };
// 每个元素存放着一个行指针,指向一个int[3]数组的首地址
// 所以,matrix[0]就是第一个一维数组的行指针。它是一个地址。
std::cout << *(matrix + 0) << " == "<< matrix[0] << std::endl; //0x62fe20 == 0x62fe20
std::cout << *(matrix + 1) << " == "<< matrix[1] << std::endl; //0x62fe30 == 0x62fe30
std::cout << *(matrix + 2) << " == "<< matrix[2] << std::endl; //0x62fe40 == 0x62fe40
// 每个行指针指向每个一维数组首元素
std::cout << **(matrix + 0) << std::endl; //输出1
std::cout << **(matrix + 1) << std::endl; //输出5
std::cout << **(matrix + 2) << std::endl; //输出9
为什么不能将二维数组名强制转换成二级指针?
因为二维数组名是:数组指针
因为二维数组名只是一个一级指针,指向一个数组。而这个数组,又包含了指向每个一维数组的指针。
什么是数组指针?
数组指针是一个指针,指向一个特定类型的数组。
// 圆括号不能省略,因为[]具有更高的优先级
// int *ptr[4]声明的是一个元素为int *的数组(指针数组)
int (*ptr)[4]; //ptr指向int[4]类型的数组
也可以这样定义:
typedef int int_array[4];
int_array *ptr = matrix;
所以,对于二维数组int matrix[3][4],二维数组名matrix可以表示为一个数组指针。被指向的数组的每个元素,是一个一维数组。
int (*ptr)[4];
ptr = matrix;
std::cout << *ptr << " == "<< matrix[0] << std::endl; //0x62fe10 == 0x62fe10 指向matrix的第1行
std::cout << *(ptr+1) << " == "<< matrix[1] << std::endl; //0x62fe10 == 0x62fe10 指向matrix的第2行
std::cout << *(ptr+2) << " == "<< matrix[2] << std::endl; //0x62fe10 == 0x62fe10 指向matrix的第3行
那么,可以用(*ptr+n)[i]来表示每个一维数组中的元素
std::cout << (*ptr)[0] << " == "<< matrix[0][0] << std::endl; //1 == 1
std::cout << (*(ptr + 1))[1] << " == "<< matrix[1][1] << std::endl; //6 == 6
std::cout << (*(ptr + 2))[2] << " == "<< matrix[2][2] << std::endl; //11 == 11
因此,文章开头的程序中PrintMatrixClockWisely函数的定义改成如下形式就能将二维数组matrix做为实参传入:
void PrintMatrixClockWisely(int (*numbers)[4], int columns, int rows)
// 或
void PrintMatrixClockWisely(int numbers[][4], int columns, int rows)
那怎样将二维数组名传给二级指针?
首先,二级指针能与指针数组相互转换。那么将二维数组转换成指针数组,不就可以转换成二级指针了吗?参考如下:
int *ptr_arr[3]; //指针数组
for(int i = 0; i < 3; ++i)
{
ptr_arr[i] = matrix[i];
}
PrintMatrixClockWisely(ptr_arr, 3, 4);
之前有些地方没有表述清楚,搞得自己也是一知半解,还让其他学友一起看了。对不起哈。