摘自: https://blog.csdn.net/ylbs110/article/details/51399235?utm_source=itdadao&utm_medium=referral

需求

今天在学习数据结构和算法时遇到一个需要传递多维数组形参的问题。问题本身很简单,向方法传递一个二维数组,但是使用的时候为了能够让数组维度值能够动态可变(比如向同一个方法传递 3X3 矩阵或者 4X4 矩阵),也还是费了些脑子。

实现

一维数组

看多维数组形参传递之前我们先看看简单的一维数组

void arrTest(int arr[2]){
    cout << sizeof(arr) << endl;
}

这几乎是最简单的数组传递方式了,但是通常不推荐这么写,因为这样一来你就无法在方法内获取数组长度了:你可以试试将 2 改为 3,4 或者其他任何数,输出的都是 int 类型数组所占的大小。
当然你可以说我已经数组长度为 2 了还要获取数组长度做什么。好问题,对于一个你已经确定长度的需求来说这么写没问题,但是实际操作中常常需要传递可变长度数组或者根据项目变化需要修改数组长度,这个时候再来修改这个 2 可能就很麻烦了,尤其是方法内多个地方用到这个长度或者多个方法都涉及到这个长度。这个时候我们就需要将参数传递到数组里面了:

void arrTest0(int arr[],int n){
    cout << arr[n - 1] << endl;
}

其中 arr[] 是数组,n 是长度。当然,如果你知道长度,比如长度为 2,写为 void arrTest0(int arr[2],int n) 也是没问题的,编译可以通过,但是如果你传入的数组长度不为 2,运行时就会报错,所以还是将这个长度空出来比较好。这里的 arr[] 实际上是作为指向数组的指针来处理的,所以上面的写法等价于:

void arrTest1(int* arr, int n){
    cout << arr[n - 1] << endl;
}

测试:

int arr1[2] = { 1, 2 };
arrTest(arr1);
arrTest0(arr1, 2);
arrTest1(arr1, 2);

结果:
4
2
2
好了,一维数组就到此为止,我们下面进入正题:多维数组。

多维数组

为了测试方便,我使用二维数组来测试,更高维度的数组使用方式和二维数组基本相同,读者自行扩展。
首先来看最基本的写法:

void arrTest2(int arr[][3], int n){
    cout << arr[n - 1][2] << endl;
}

其中 arr[][3] 是数组,n 是数组第一维的维度,除了地以维之外,其他所有维度必须预设维度,也就是说 arr[][] 编译不会通过。这样就比较蛋疼了,如果我并不知道数组长度怎么办,或者手一抖将 arr[n - 1][2] 写为了 arr[n - 1][3] 怎么办(我写这篇文章的时候最开始就写为了 arr[n - 1][3])?当然有办法,强大的 C++ 早就给我们预留了实现机制:数组名称本质上是指针,对数组的操作基本等同于对指针的操作。于是,上面的写法就可以使用指向一维数组的指针来代替了:

void arrTest3(int* arr[], int n){
    cout << arr[n - 1][n - 1] << endl;
}

更加通用的,我们连一维数组也改为指针,这样对于任意维度的数组我们可以写出通用的传参模式:

void arrTest4(int** arr, int n){
    cout << arr[n - 1][n - 1] << endl;
}

看到这里貌似万事大吉皆大欢喜,但是剧情往往并不如想象中发展,一些幺蛾子总要出来给我们捣点乱:对于 arrTest2,我们可以直接将一个二维数组名作为参数传递进来,但是对于 arrTest3 和 arrTest4,直接传递数组形参会报错(int (*)[3]类型的实参与 int **类型的形参不兼容),看来我们得想法办法将数组转换为int **类型。这个还比较麻烦,我在网上找了半天发现得先定义一个int **指针,然后将数组的每一维度逐一传递给该指针:

int* r[3];
for (int i = 0; i < 3; i++)
        r[i] = arr2[i];

上面 arr2 是数组。注意,int* r[3] 不能写为 int** r,这样在赋值的时候会提示没有初始化。
如果你有更好的方式请告诉我,不胜感激!!!

测试:

    int arr2[3][3] = { { 11, 12, 13 }, { 21, 22, 23 }, { 31, 32, 33 } };
    arrTest2(arr2,3);
    int* r[3];
    for (int i = 0; i < 3; i++)
        r[i] = arr2[i];
    arrTest3(r, 3);
    arrTest4(r, 3);

结果:
33
33
33

转载请注明出处:http://blog.csdn.net/ylbs110/article/details/51399235

完整代码

#include "stdafx.h"
#include <iostream>

using namespace std;

void arrTest(int arr[2]){
    cout << sizeof(arr) << endl;
}
void arrTest0(int arr[],int n){
    cout << arr[n - 1] << endl;
}
void arrTest1(int* arr, int n){
    cout << arr[n - 1] << endl;
}
void arrTest2(int arr[][3], int n){
    cout << arr[n - 1][2] << endl;
}
void arrTest3(int* arr[], int n){
    cout << arr[n - 1][n - 1] << endl;
}
void arrTest4(int** arr, int n){
    cout << arr[n - 1][n - 1] << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
    int arr1[2] = { 1, 2 };
    arrTest(arr1);
    arrTest0(arr1, 2);
    arrTest1(arr1, 2);

    int arr2[3][3] = { { 11, 12, 13 }, { 21, 22, 23 }, { 31, 32, 33 } };
    arrTest2(arr2,3);
    int* r[3];
    for (int i = 0; i < 3; i++)
        r[i] = arr2[i];
    arrTest3(r, 3);
    arrTest4(r, 3);
    system("pause");
    return 0;
}