前言
多维数组中,二维数组是最常用的一种。在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环境下的运行结果。
左图为VS Code;有图为VS 2015
优缺点评价
这里先给出结论,最推荐使用方式3。下面是简要的分析。
- 方式1和方式2实质上是相同的。它们适用性很好。但是,它们定义必须事先给出第二维的长度,即不是对任意大小的二维数组都适用。
- 方式3适用性同样很好,对任意大小的二维数组都适用。但是,它是最难理解的。理解它需要对二维数组元素的结构、二维数组元素的储存以及二维数组与指针的关系有比较深刻的理解。
- 方式4是最容易理解的了。但是,它的适用性最差。
最后需要强调的是,对于该程序的求和函数,更安全、更易读的写法是将参数列表中接受二维数组数据的参数加上const修饰。本程序没加的原因是为了更好的突出其功能。const修饰的对象不同,产生的效果也不同。如果参数列表中接受二维数组数据的参数加上const修饰,它将无法修改二维数组的数据;如果只有待传入的二维数组是用const修饰,参数列表中的参数不是const修饰的,那么上述方式都不被允许。因此,请根据实际情况,自行决定const的修饰对象和修饰位置。
参考文献
Stephen Prata写的《C Primer Plus》第五版