C语言 二维数组作为函数参数的4种方式

前言

多维数组中,二维数组是最常用的一种。在C语言编程中,二维数组的定义、取值以及赋值都比较容易,与一维数组类似。然而,在将二维数组作为函数参数传递时,参数结构较复杂,难以理解。本文章是实用型文章,注重代码使用,不会讲述过多理论。如果想要学习理论知识(非常推荐,可以对代码的理解更透彻),可以查阅下方参考文献列出书籍的第10章内容。话不多说,下面将给出一个C程序,以展示二维数组作为函数参数的4种方式。注:下面的代码已在VS Code(使用Mingw64)和VS 2015下编译运行过。

正文

下面程序的功能是对一个int型二维数组的所有元素进行求和,并分别把求和结果打印在屏幕上。根据二维数组传入函数的方式,定义了4个版本的求和函数。

 

#include 

#define ROW 2   //二维数组的行数
#define COL 2   //二维数组的列数

//4个版本的求和函数
//方式一:数组形式
int TwoDimArraySum1(int twoDimAr[][COL], int row, int col);

//方式二:指针形式,prArray是一个指向包含COL个int的数组的指针
int TwoDimArraySum2(int (*prArray)[COL], int row, int col);

//方式三:指针形式,pr是一个指向int的指针
int TwoDimArraySum3(int *pr, int row, int col);

//方式四:变长数组(C99开始支持)
int TwoDimArraySum4(int row, int col, int twoDimAr[row][col]);

int main(void)
{
    int twoDimArray[ROW][COL] = {{-2, 5}, {4, 9}};
    int result;

    //方式一
    result = TwoDimArraySum1(twoDimArray, ROW, COL);
    printf("Sum1函数结果:%d\n", result);

    //方式二
    result = TwoDimArraySum2(twoDimArray, ROW, COL);
    printf("Sum2函数结果:%d\n", result);

    //方式三
    result = TwoDimArraySum3(twoDimArray[0], ROW, COL);
    printf("Sum3函数结果:%d\n", result);

    //方式四
    result = TwoDimArraySum4(ROW, COL, twoDimArray);
    printf("Sum4函数结果:%d\n", result);

    return 0;
}

int TwoDimArraySum1(int twoDimAr[][COL], int row, int col)
{
    int i, j;
    int result = 0;

    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            //下面两种寻址方式都行
            result += twoDimAr[i][j];
            // result += *(*(twoDimAr + i) + j);
        }
    }
    return result;
}

int TwoDimArraySum2(int (*prArray)[COL], int row, int col)
{
    int i, j;
    int result = 0;

    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            //下面两种寻址方式都行
            result += prArray[i][j];
            // result += *(*(prArray + i) + j);
        }
    }
    return result;
}

int TwoDimArraySum3(int *pr, int row, int col)
{
    int i, j;
    int result = 0;

    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            //下面两种寻址方式都行
            result += pr[i*row + j];
            // result += *(Pr + i*row + j);
        }
    }
    return result;
}

int TwoDimArraySum4(int row, int col, int twoDimAr[row][col])
{
   int i, j;
   int result = 0;

   for (int i = 0; i < row; i++)
   {
       for (int j = 0; j < col; j++)
       {
           //下面两种寻址方式都行
           result += twoDimAr[i][j];
           // result += *(*(prArray + i) + j);
       }
   }
   return result;
}

 

正如程序注释所言,方式4(变长数组)是C99开始支持的,不是所有编译器都支持。例如,VS 2015就不支持该语法。因此,在VS 2015环境下运行时,方式4被注释了。下面给出VS Code(基于Mingw64)以及VS 2015环境下的运行结果。

C语言 二维数组作为函数参数的4种方式_第1张图片

左图为VS Code;有图为VS 2015

优缺点评价

这里先给出结论,最推荐使用方式3。下面是简要的分析。

  • 方式1和方式2实质上是相同的。它们适用性很好。但是,它们定义必须事先给出第二维的长度,即不是对任意大小的二维数组都适用。
  • 方式3适用性同样很好,对任意大小的二维数组都适用。但是,它是最难理解的。理解它需要对二维数组元素的结构、二维数组元素的储存以及二维数组与指针的关系有比较深刻的理解。
  • 方式4是最容易理解的了。但是,它的适用性最差。

最后需要强调的是,对于该程序的求和函数,更安全、更易读的写法是将参数列表中接受二维数组数据的参数加上const修饰本程序没加的原因是为了更好的突出其功能。const修饰的对象不同,产生的效果也不同。如果参数列表中接受二维数组数据的参数加上const修饰,它将无法修改二维数组的数据;如果只有待传入的二维数组是用const修饰,参数列表中的参数不是const修饰的,那么上述方式都不被允许。因此,请根据实际情况,自行决定const的修饰对象和修饰位置。

参考文献

Stephen Prata写的《C Primer Plus》第五版

你可能感兴趣的:(C语言 二维数组作为函数参数的4种方式)