函数参数设计(CSEN-e小白管理员Half_word编写)
函数参数设计
说起这个话题,可能会被DaLao一笑划过;函数设计有什么难的?无外乎实现传入某些参数,内部实现某种算法,再反馈一个结果给调用者。
的却如此,对于函数;返回值我们只有一个,内化的算法之类诸君自行探寻;所以本文目的主要是探寻函数参数的设计。如果知晓其中奥妙的读者不妨移步其它文章。
正文:
1.你的的函数参数长啥样?
以C语言为例,相信大家学完函数设计之后肯定对于参数设计有许多自己的体会。无论是整形,字符型,甚至是各类指针参数都了然于心。
巴特,大家会对于参数的排列有要求吗?如果要你设计一个有10个以上类型各异的函数;你会如何设计?
如果读者给出的答案是下面这种:
void Func(int count, long Lenth, char* List, unsigned int Source, 等等等等);
上述的传统设计方案,固然没有任何错误,大部分语言设计教材教给我们的都是这种案。但是,这就不得不面对一个致命问题----函数可读性差,且显得臃肿(一般这种方案设计,必须采取多次续行才能将参数一一放下)。有读者可能会反驳可读性,但是事实就是如此,一大片的函数头看着就是十分不舒服。
2. 如何设计参数才能让上述问题得到解决?
笔者给出一种方案:结构体化设计你的一堆参数。
相信一提到在,有过Win32API使用的同学会恍然大悟;这种手法对于成熟的工程库很常见。
即将相关性较大的参数尽量放入一个结构体中,使得函数参数数量控制在3~4个之际。最终得到简化函数的使用的目的。
但是这种设计也还是需要面对一个问题:参数值初始化。所以也就引出下面的话题。
3. 设计这种参数的初始化函数,给一种默认处理方案。
对于一个包含众多参数的结构体,其初始化尽量遵循:“变量填0,指针指NULL“
为何?强迫使用者规范变量的初始化。给需要用到结构体的函数设定一种简易的默认运行动作。下方给出初始化函数设计具体实例。
bool InitFunc(struct FuncStruct* Default)
{
Default->Count = 0;
Default->Lenth = 0;
Default->List = NULL;
Default->Source = 0;
//……其它参数尽量按照原则
return 1;
}
4.参数中的特例 ---- 回调函数。
在此处插入这个话题有些突兀,但是也是需要警惕的。对于回调函数,尽量将其函数地址以及参数整合在一个结构体内;所以上述初始化操作显得格外重要,一旦回调函数参数传递不正确,程序多半崩溃,而且查验极为困难。
5. 设计禁忌?goto语句的使用
最后聊一点老师不让干的活----goto语句,相信第一次学习某种高级语言,老师都会对你说:goto和标签一起使用,但是现在不用了,容易带出BUG。或者直接回避。
但是,goto的前身可是汇编的专用:跳转指令。如果其真的如讲述的那般不堪,那为何还有这么多语言仍然保留?可见,goto仍有其值得学习的点。
引入下列问题:
多层循环嵌套中,如何从最内层直接跳出所有循环?
解决方案最经典的是:修改最外层循环成立条件,使得循环终止。但是最外层循环如果是while(1)呢?
这时候只有使用goto,(也许有小伙伴会说用longjump(),但是本质还是此类跳转,仅仅距离不同).
代码如下:

可见,某些异常处理有goto这类跳转指令显然解决更加轻松了。
但是务必记住:goto被人诟病最多的就是滥用,每次的跳转都应当是迫不得已的终止;往前跳一般会让你的代码产生BUG.
(Ps:setjump与longjump()请读者自行查阅使用,并且比较与goto的差别。)