【C语言实战经验2】你见过全局变量满天飞的代码吗?如何规避?
本帖最后由 dffzh 于 2025-5-9 17:22 编辑#申请原创#
@21小跑堂
从事软件开发的你是否见过全局变量满天飞的代码?
是否见过全局搜索全局变量后会弹出来N个调用的情况?然后来一句“Oh, My god”…
反正我见过,长得类似下面这些代码(紫色的变量为全局变量):
简单解释一下全局变量:又叫外部变量,其作用域为整个文件或整个代码工程。从它的解释就可以看出,全局变量使用起来确实方便;但是,在代码量多且比较复杂的程序里,如果过度使用全局变量,则会导致不仅限于以下的常见问题:代码耦合度高:很多源文件里都有对全局变量的读写操作,代码相互耦合;调试难度大:遇到Bug时,由于读写全局变量的代码段太多,排查难度变大;可维护性差:软件版本迭代或者移交给其他同事,可能人家需要花费大量精力去理解;健壮性差:全局变量在整个工程被读写操作,特别是出现在临界代码区或者中断函数里面时,代码稳定性显著降低,容易出现意想不到的偶发性Bug。可能还有其他问题,特别是在基于操作系统的软件开发应用中,因此,作者强烈建议尽量少用或者尽量不直接暴露全局变量。那问题又来了,我不用全局变量,那用啥?到底有哪些方法可以减少全局变量的使用频次呢?这篇文章作者将通过一些实战经验代码与大家分享一下如何减少全局变量的使用。
1、使用静态变量替换全局变量不推荐使用全局变量实现的计数器功能代码: int counter = 0;counter++;推荐使用用函数封装+静态变量实现:int count(void){ static int counter = 0; counter++; return counter;}
2、使用结构体封装数据不推荐直接使用全局变量定义长方形的长,宽和面积:float length =0;float width = 0;float area = 0;推荐使用结构体来封装数据,便于管理:typedef struct{ float length;float width;float area;}st_rectangle;
3、使用函数参数传递数据
不推荐如下方式传递数据:int value;void set_para(void){ value = 66;}推荐使用如下方式:void set_para(int *value){ *value = 66;}
4、使用函数返回值替代全局变量不推荐如下方式读取数据:int result;void calculate(void) { result = get_state();}推荐如下方式读取数据:int calculate(void) { return get_state();}
5、加static限制全局变量的作用域可以在指定的源文件里定义一个带static关键词的静态全局变量,则该全局变量只能在该文件里被使用,其他文件无权访问:static int counter;如果只是在某个源文件内部使用的变量,就一定要定义为静态变量!
6、使用局部结构体指针变量间接操作在函数内部需要频繁操作某个全局结构体变量时,可以定义一个局部结构体指针变量,来指向这个全局结构体变量,通过操作局部结构体指针变量即可达到更新全局结构体变量的效果:typedef struct{ float length;float width;float area;}st_rectangle;st_rectangle g_stRectangle; //全局结构体变量
void func(void){ //定义一个局部结构体指针变量,指向全局结构体变量 st_rectangle *pRectangle =&g_stRectangle;//……//在函数内部操作pRectangle等同于操作g_stRectangle}方法2和方法6相结合的应用方法,你一定要知道,它将会让你写的代码有质的飞跃!
举个作者自己开发的例子:这样这个函数里其实就出现了一次st_loadcell_config这个全局变量;而且如果你修改了pLoadcellConfig的成员变量,也就是直接修改了st_loadcell_config的成员变量,一箭双雕,何乐而不为?
7、使用局部变量替换全局变量如果只是在函数内部使用的变量,就一定要定义为局部变量!当然如果是大数组,就要慎重。
通过以上的一些方法,可以显著减少全局变量的使用,提高代码的模块化程度和可维护性。当确实需要全局变量时,可以考虑将其封装在结构体中,并通过访问函数的方式来操作,而不是直接暴露全局变量。以上是作者的一些经验,分享出来,希望对你有所帮助。
如果你有更多更好的减少全局变量使用的方法,欢迎来贴分享和讨论!
让我们一起向全局变量满天飞的代码 say godbye!
看的是云里雾里的 @21小跑堂 管理员,帮原创审核{:handshake:} 这个要看代码量,其实面向对象的写法看起来也很累。 Chad1989 发表于 2025-5-27 13:34
这个要看代码量,其实面向对象的写法看起来也很累。面向对象的确实相对难理解一点。 收益良多,收藏起来 bushiliang 发表于 2025-5-29 01:58
收益良多,收藏起来有用就好,知识共享!{:handshake:} 全局变量在整个工程被读写操作,容易出现意想不到的偶发性Bug。 forgot 发表于 2025-5-30 09:01
全局变量在整个工程被读写操作,容易出现意想不到的偶发性Bug。
是的,特别是有些地方必须要加volatile关键字声明而实际没有加的全局变量,比如在中断服务程序里进行写操作的全局变量,如果不加volatile声明,就极易出现偶发性Bug。
页:
[1]