单片机程序最易范的错误是全局变量到处飞, 这个现象在早期写汇编转型过来的程序员以及初学者中常见,这帮家伙几乎把全局变量当作函数形参来用,多数的.h文档里面一堆的结构体定义和extern,这个模块里边赋值123,那个模块里边判断123分支决定做什么。每当看到这种程序,我总要戚眉变脸而后拍桌喝骂。我不否认全局变量的重要性,但我认为要谨慎地使用它,滥用全局变量会引申带来其它更为严重的结构性问题。诸位看官,且听我细细道来。
1它会造成不必要的常量频繁使用,特别当这个常量没有用宏定义“正名”时,代码阅读起来将万分吃力。
2.它会导致软件分层的不合理,全局变量相当于一条快捷通道,它使得程序员模糊了“设备层”和“应用层”之间的边界。写出来的底层程序容易多情地关注起上层的应用。这在软件系统的初期或许功能调试进度一日千里,但到了后期往往bug一堆,处处“补丁”,雷区遍布。说是度日如年举步维艰,也不夸张的。
3.由于软件的分层不合理,到了后期维护,哪怕仅是增加修改删除小功能,往往要从上到下掘地三尺地修改,涉及大多数模块,而原有的代码注释却忘了更新修改,这个时候,交给后来维护者的系统会越来越像一个“泥潭”,注释的唯一作用就是为了使泥潭上方充满迷烟瘴气。
4.不必多言,你已经成功得到一个畸形的系统,它处于一个神秘的稳定状态!
然后我告诉大家现实意义的后果是什么。
1.“老人”气昂昂,因为系统离不开他,所有“雷区”只有他了然于心。当出现紧急的bug时,只有他能够搞定。你不但不能辞退他,还要给他加薪。
2.新人见光死,但凡招聘来维护这个系统的,除了改出更多的bug外,基本上一个月内就走人,到了外面还宣扬这个公司的软件质量有够差够烂。
3.虽然产品的升级,几个月没有接触这个系统的原创者会发现,很多雷区他本人也忘记了,每次的产品升级周期越来越长,因为修改一个功能会冒出很多bug,而按下一个bug,会弹出其他更多的bug,在这期间,会产生更多的全局变量。有一天他告诉老板,不行啦不行啦,资源不够了,ram或者flash空间太小了,升级升级。
4.客户投诉不断,售后快崩溃了,业务员也尽量不推荐此产品了,市场份额越来越小,公司形象越来越糟糕。
要问我的对策吗,只有两个原则:
1.能不用全局变量尽量不用,我想除了系统参数、通信处理和一些需要效率的处理模块,其他的基本可以靠合理的软件分层和编程技巧来解决。
2.如果用了,能藏多深就藏多深。如果只有该.c文件用,就static到该文件中,顺便把结构体定义也收进来;如果只有一个函数用,那就static到函数里面去;如果非要开放出去让人读取,那就用函数return出去,这样就是只读属性了;如果非要遭人蹂躏赋值,好吧,我还可以严格控制我的.h档被谁包含,而不是放到公共的includes.h中被人围观,丢人现眼。
如此,你可明白我对全局变量的感悟有多深刻。悲催的我,已经把当年那些老人交给我维护的那些案子加班重新翻写了。你能明白吗,请不要让人背后唾弃你。