C语⾔⼆维数组作为函数参数的4种⽅式
前⾔
多维数组中,⼆维数组是最常⽤的⼀种。在C语⾔编程中,⼆维数组的定义、取值以及赋值都⽐较容易,与⼀维数组类似。然⽽,在将⼆维数组作为函数参数传递时,参数结构较复杂,难以理解。本⽂章是实⽤型⽂章,注重代码使⽤,不会讲述过多理论。如果想要学习理论知识(⾮常推荐,可以对代码的理解更透彻),可以查阅下⽅参考⽂献列出书籍的第10章内容。话不多说,下⾯将给出⼀个C程序,以展⽰⼆维数组作为函数参数的4种⽅式。注:下⾯的代码已在VS Code(使⽤Mingw64)和VS 2015下编译运⾏过。
正⽂
下⾯程序的功能是对⼀个int型⼆维数组的所有元素进⾏求和,并分别把求和结果打印在屏幕上。根据⼆维数组传⼊函数的⽅式,定义了4个版本的求和函数。
#include <stdio.h>
#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*col + j];
// result += *(Pr + i*col + j);
}
}
return result;
}
int TwoDimArraySum4(int row, int col, int twoDimAr[row][col])
{
int i, j;
int result = 0;
c语言二维数组表示方法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的修饰对象和修饰位置。
关于更⾼维数组
对于更⾼维的数组,上⾯四种⽅式仍然适⽤。除了⽅式3外,另外三种⽅式都很容易扩展成更⾼维的。对于⽅式3,虽然最推荐它,但是它随着维数的增多,它变得更复杂更难理解。⽽且基于⽅式3,还可以延伸出其他⽅式。这⾥以三维数组举例,⽅式3还可以延伸出这样⼀种⽅式,该⽅式中接受三维数组的形参是⼀个指向⼀维数组的指针。对于这种由⽅式3延伸的⽅式,我是不推荐的,它⽐⽅式3更复杂,使⽤它还不如使⽤⽅式3。
参考⽂献
Stephen Prata写的《C Primer Plus》第五版
博主:(主博客)
个性签名:如果你愿意努⼒,⼈⽣最坏的结果也不过是⼤器晚成。
------------------------------------------------------------------------------------
如果这篇⽂章对你帮助的话,记得在下⽅点赞哦,博主在此感谢!
如果对这篇⽂章有疑问,请在评论区指出,欢迎探讨,共同进步。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论