C言语函数调用:【舛误码】和【前去值】通报的小思虑

发布日期:2022-08-07 02:24    点击次数:162

C 言语是一门面向进程的编程言语,经由过程一个又一个函数,把计算、进程掌握等逻辑,包装成一个个独立的处理惩罚单元。

既然是函数调用,就必定会有参数和前去值的通报成就,因而也就孕育发生了多种差别的编程范式,比喻:

Posix 风格:函数前去值只用来默示告成(0)或失利(非0),别的的输出终局都运用参数来通报。 Unix 风格:函数前去值即蕴含舛误代码,也蕴含有效的输出终局。 GAI 风格:与 Posix 有点近似,函数执行告成时前去0,否则就前去非0。

这篇文章就来放松一下,聊一聊这些函数调用范式在开发进程中的一些小思虑。

我们假设有一个算法函数,输入两个整型参数,输出一个整型终局,并且输出一个舛误代码。

第一种:输入、输出终局和舛误码整个经由过程参数通报

既然全体的信息都是经由过程参数来通报的,那末函数定义就该当是下面这样:

void func1(int a, int b, int *result, int *err_code) {     int c = a + b;     *result = c;     err_code = 0;  // 相沿 Linux 中的习性,0 默示没有发生舛误。 } 

因为不必要前去任何数据,因而函数签名的前去范例就是 void 。

因为调用者必要取得输出终局和舛误码,因而在形参中, result和err_code必要通报指针范例的变量。

面对这样的函数签名,调用者就必须体现的定义两个变量result和err_code,用来领受函数的输出。

// 调用者代码  int result, err_code; func(1, 2, &result, &err_code); if (0 == err_code)     printf("Success. result = %d \n", result); else     printf("Failed. err_code = %d \n", err_code); 

这类函数范式的所长就是:在调用模式上统一,不管参数范例是什么(底子范例、组织体等待),都是整齐齐截的函数调用写法。

弱点就是有点肩负。

面对任何一个函数,调用者都必须定义一个err_code变量通报出来。

假设一个函数是进程掌握范例的,压根就不会孕育发生什么舛误码,这样的函数调用就显得很臃肿,因为调用者压根就不必要查抄舛误码。

第二种:函数前去值默示舛误码

也就是把第一种要领中的err_code参数,经由过程函数前去值赋值给调用者。

这类函数编程范式照旧相比罕见的,前去值只默示舛误码,别的的输出终局都经由过程参数引用(指针)来通报。

int func2(int a,演出案例 int b, int *result) {     int c = a + b;     *result = c;     return 0;   // 前去舛误码 } 

这样的函数范式跟POSIX风格很像了。

面对这样的函数,调用者的写法就会变成这样:

// 调用者代码  int result, err_code; err_code = func2(1, 2, &result); if (0 == err_code)     printf("Success. result = %d \n", result); else     printf("Failed. err_code = %d \n", err_code); 

看起来彷佛跟第一种要领没有什么本质差别,然则再看一下下面这样的写法呢:

// 调用者代码  int result; if (0 == func2(1, 2, &result))     printf("Success. result = %d \n", result); else     printf("Failed.\n"); 

这样的代码风格,在Linux中是否是很罕见?当不必要处理惩罚舛误码时,这样的编程要领会更方便一些。

第三种:函数前去值默示输出终局

也就是把第一种要领中的result参数,经由过程函数前去值赋值给调用者。

int func3(int a, int b, int *err_code) {     int c = a + b;     err_code = 0;     return c; } 

这有点近似Unix中的风格:

前去终局中蕴含了有效的数据,然则它有一个范围:前去终局必须与舛误码的范例分歧。

此外另有一个成就:假设 int 型的前去终局也兴许是正数, 所以 Unix 中还必须运用另外一个全局变量 errno 来零丁存储舛误码,存在线程安好成就(可运用线程部门存储来经管)。

面对这样的函数签名,调用者的调用要领以下:

// 调用者代码  int result, err_code; result = func3(1, 2, &err_code))  if (0 == err_code)     printf("Success. result = %d \n", result); else     printf("Failed.\n"); 

这类要领的弱点与第一种同样:必须定义一个变量 err_code,来领受舛误码。

在毋庸要查抄舛误码的场合中,显得有点画蛇添足。

小结

以上的这三种函数调用要领,没无短长之分,只与每一位开发者的编码习性有纠葛。

并且无理论的名目代码中,这三种要领都能看失去。

假设函数输出终局是组织体呢?

刚刚探究的三种要领中,函数输出终局reuslt是一个整型,假设它是一个组织体范例的变量,那末哪类要领相对比拟好呢?

这就要留心此外两点了:

组织体的赋值是必要时光开销的;

组织体赋值时,必要推敲深拷贝、浅拷贝的成就;

当看完以上几个小思虑时,是否是感应特殊俭朴、五体投地?

没关系延续思虑一步:在我们的理论编程进程中,是否是每次兴许留心、恪守这些小细节成就呢?

假设团队中没有强逼的代码尺度,同事之间不会code review,我们是否是都市抉择偷懒、放过自身呢?我就是^-^

本文转载自微信群众号「IOT物联网小镇」,可以或许经由过程下列二维码关注。转载本文请联络IOT物联网小镇群众号。

 



栏目分类



Powered by 【欧冠体育官方入口】 @2013-2022 RSS地图 HTML地图