C语言是面向过程的编程语言。独立的处理单元。既然是函数调用,必然存在传递参数和返回值的问题,所以编程范式有很多种,例如:Posix风格:函数的返回值只是用来表示成功(0)或失败(非零),其他输出结果使用参数传递。Unix风格:函数返回值包括错误代码以及有用的输出。GAI风格:与Posix类似,函数执行成功则返回0,否则返回非零。在本文中,我们就放轻松,谈谈这些函数调用范式在开发过程中的一些小思考。我们假设有一个算法函数,输入两个整数参数,输出一个整数结果,输出一个错误码。第一种:输入、输出结果和错误码都是通过参数传递的。由于所有信息都是通过参数传递的,函数定义应该如下:voidfunc1(inta,intb,int*result,int*err_code){intc=a+b;*result=c;err_code=0;//使用在Linux中习惯,0表示没有错误发生。}因为不需要返回任何数据,函数签名的返回类型为void。因为调用者需要获取输出结果和错误码,所以在形参中,result和err_code需要传递指针类型的变量。面对这样的函数签名,调用者必须显式定义两个变量result和err_code来接收函数的输出。//调用者代码intresult,err_code;func(1,2,&result,&err_code);if(0==err_code)printf("Success.result=%d\n",result);elseprintf("Failed.err_code=%d\n",err_code);这种函数范式的好处是在调用形式上是统一的,无论参数类型是什么(基本类型、结构体等),都是统一的函数调用写法。缺点是有点麻烦。面对任何函数,调用者必须定义一个err_code变量并传入。如果一个函数是过程控制类型的,那么根本不会产生错误码,这样的函数调用会显得臃肿,因为调用者根本不需要检查错误码。方法二:函数返回值表示错误码,即方法一中的err_code参数通过函数返回值赋值给调用者。这种函数式编程范式是比较常见的。返回值仅表示错误代码,其他输出结果通过参数引用(指针)传递。intfunc2(inta,intb,int*result){intc=a+b;*result=c;return0;//返回错误码}的函数范式与POSIX风格非常相似。面对这样的函数,调用者的写法会变成这样://Callercodeintresult,err_code;err_code=func2(1,2,&result);if(0==err_code)printf("Success.result=%d\n",result);elseprintf("Failed.err_code=%d\n",err_code);看起来和第一种方法没有本质区别,但是看下面的写法://Callercodeintresult;if(0==func2(1,2,&result))printf("Success.result=%d\n",result);elseprintf("失败。\n");这样的代码风格,在linux中是不是很常见?这种编程方式在不需要处理错误码的时候比较方便。第三种方式:函数返回值表示输出结果,即通过函数返回值将第一种方式中的结果参数赋值给调用者。intfunc3(inta,intb,int*err_code){intc=a+b;err_code=0;returnc;}这有点类似于Unix中的风格:返回结果中包含有用的数据,但它有一个限制:返回结果必须与错误码类型一致。还有一个问题:如果int类型的返回结果也可能为负数,那么在Unix中必须使用另一个全局变量errno来单独存放错误码,存在线程安全问题(可以使用thread来解决本地存储)。面对这样的函数签名,调用者的调用方法如下://callercodeintresult,err_code;result=func3(1,2,&err_code))if(0==err_code)printf("Success.result=%d\n",结果);elseprintf("失败。\n");这种方法的缺点与第一种相同:必须定义一个变量err_code来接收错误代码。在不需要查看错误码的场合,显得有些多余。总结以上三种函数调用方式没有好坏之分,只与每个开发者的编码习惯有关。并且在实际的项目代码中,三种方法都可以看到。如果函数输出是一个结构体怎么办?刚才讨论的三种方法中,函数输出reuslt是一个整数。如果是结构体类型的变量,哪种方式相对比较好?这里需要注意的还有两点:结构体的赋值需要时间开销;赋值结构时,需要考虑深拷贝和浅拷贝的问题;看完以上的小感想,是不是觉得特别简单,不屑一顾呢?我们再进一步思考一下:在我们实际的编程过程中,是否可以每次都注意并遵守这些小细节呢?如果团队中没有强制性的代码规范,同事间也没有代码审查,我们都会选择偷懒吗?,放自己走?我是^-^本文转载自微信公众号“IOT物联网小镇”,可通过以下二维码关注。转载本文请联系物联小镇公众号。
