将二维数组转换成二级指针

最近在写一个顺时针打印矩阵的函数时,发现二维数组名不能传递给一个二级指针。

#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);



之前有些地方没有表述清楚,搞得自己也是一知半解,还让其他学友一起看了。对不起哈。

  • 18
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值