原文链接:https://mp.weixin.qq.com/s/l7dkHHvWi7tXlpH-iKfhbg
1
函数参数的传递
既然本文谈到函数参数的个数问题,首先就需要了解函数参数到底是如何传递的,并且其影响着什么?
函数的调用过程主要是依赖函数调用栈,对于栈的原理很简单-先进后出,而对于函数调用栈主要是在该栈中分配内存以供函数临时使用-(即压栈),而当函数返回便是一个栈回溯的过程-(即出栈)。
所以函数的参数跟局部变量一样都分配到栈上,当然为了提高函数调用速度,相关变量会直接通过寄存器来传递,原理上也是类似的。
2
参数太多引起的问题
前面bug菌在谈及参数太多会导致函数调用更加的耗时,因为增加了参数入栈和出栈的时间,特别是一些循环语句中调用参数较多的子函数。
而对性能上的影响,对于大部分朋友所做的项目可能并不是很在意,快点慢点也无所谓,一般用户也体会不到,毕竟现在的芯片性能都还不错,可以为低效的代码买单。
但是参数太多对于编码风格却是大煞风景,更值得注意的是很容易让编码人员犯错。
bug菌之前就遇到一种情况:
1void Function(int param1,int param2,int param3,int param4,int param5\
2 int param6,int param7,int param8,int param9,int param10)
3{
4
5 ......
6}
7
8int main(void)
9{
10 ......
11
12 Function(Val1,Val2,Val3,Val4,Val5,Val6,Val7,Val8,Val9,Val10);
13 ......
14}
如以上代码,由于参数太多,在传递参数的过程中,传递顺序不小心错乱了,编译仍然可以正常通过,但程序就引入了bug导致出错。
3
如何处理函数参数
那参数多少才算多?
其实并没有严格的界定,因为终大量的参数定义都会在栈上分配,只要不把栈撑爆了,都是允许的。
对于C语言的参数传递,主要是两种方式,一种就是传值和传地址。
如果一个函数内部不依赖于静态全局区参数或者函数外部存储区,数据均来源于函数参数,那么随着需求不断的变化,函数功能更加的丰富多变,参数也将随着变大。
经常听有些朋友说直接把参数封装成结构体来进行传递,这样的处理虽然能够在一定程度上减少函数参数顺序错乱带来的风险,但与各参数分别传递并没有太大的改善。
就类似于如下代码:
1void process(void)
2
3{
4 sPara.m1 = 1;
5 sPara.m2 = 2;
6 sPara.m3 = 3;
7 sPara.m4 = 4;
8 .....
9
10 process(sPara);
11}
同时我个人还是不建议简单地用来减少参数数量进行数据打包,结构体应当尽量表现业务上的关联性,当然如果你一定在数据之间强加一种关系,那我也没办法。
同时一个函数一般只实现一种功能,不要把太多的功能放到一个函数中,一方面把函数写得特别长,另一方面就是会使得参数特别多,因为这些参数都和特定的功能相关。
似乎单独值传递并不能直接改善参数太多带来的弊端。
那么就必须借助函数以外的存储区来作为相关参数的存储位置,参数仅仅只是索引,更多的参数和信息还需要根据传递的地址或者是索引来获得,这样就降低了调用函数参数太多所带来的负担。
以前也跟大家介绍过一些C语言面向对象程序的设计,所有的数据和方法都会封装到一个结构体对象中,这对于相关方法函数的调用只需要传递相应的对象地址给形参指针,一个指针多大?应该不用我多说了吧。
后
好了,今天就跟大家分享这么多了,都是bug菌平时总结的C语言编程技巧,好好品味一下,如果你觉得有所收获,一定记得点个赞~