现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

尽量不要使用全局变量

2014-12-20 16:06 工业·编程 ⁄ 共 1027字 ⁄ 字号 评论 3 条

1. 能不用全局变量尽量不用,我想除了系统状态和控制参数、通信处理和一些需要效率的模块,其他的基本可以靠合理的软件分层和编程技巧来解决。

2. 如果不可避免需要用到,那能藏多深就藏多深。

1)如果只有某.c文件用,就static到该文件中,顺便把结构体定义也收进来;

2)如果只有一个函数用,那就static到函数里面去;

3)如果非要开放出去让人读取,那就用函数return出去,这样就是只读属性了;

4)如果非要遭人蹂躏赋值,好吧,我开放函数接口让你传参赋值;5)实在非要extern**我,我还可以严格控制包含我.h档的对象,而不是放到公共的includes.h中被人围观,丢人现眼。

如此,你可明白我对全局变量的感悟有多深刻。悲催的我,已经把当年那些“老人”交给我维护的那些案子加班全部重新翻写了。你能明白吗,不要让人背后唾弃你哦。

对于一些网友提到的,如果大量使用局部变量也会容易造成栈溢出的问题,还提到程序模型的概念。言之有理。所以特地来补充一下意见:

1.全局变量是不可避免要用到的,每一个设备底层几乎都需要它来记录当前状态,控制时序,起承转合。但是尽量不要用来传递参数,这个很忌讳的。

2.尽量把变量的作用范围控制在使用它的模块里面,如果其他模块要访问,就开个读或写函数接口出来,严格控制访问范围。这一点,C++的private属性就是这么干的。这对将来程序的调试也很有好处。C语言之所以有++版本,很大原因就是为了控制它的灵活性,要说面向对象的思想,C语言早已有之,亦可实现。

3.当一个模块里面的全局变量超过3个(含)时,就用结构体包起来吧。要归0便一起归0,省得丢三落四的。

4.在函数里面开个静态的全局变量,全局数组,是不占用栈空间的。只是有些编译器对于大块的全局数组,会放到和一般变量不同的地址区。若是在keil C51,因为是静态编译,栈爆掉了会报警,所以大可以尽情驰骋,注意交通规则就是了。

5.单片机的os-less系统中,只有栈没有堆的用法,那些默认对堆分配空间的“startup.s”,可以大胆的把堆空间干掉。

6.程序模型?如何分析抽象出来呢,从哪个角度进行模型构建呢?很愿意聆听网友的意见。

本人一直以来都是从两个角度分析系统,事件--状态机迁移图 和 数据流图,前者分析控制流向,完善UI,后者可知晓系统数据的缘起缘灭。这些理论,院校的《软件工程》教材都有,大家不妨借鉴下。只不过那些理论,终究是起源于大型系统软件管理的,牛刀杀鸡,还是要裁剪一下的。

目前有 3 条留言    访客:3 条, 博主:0 条

  1. 爱求索 2015年02月08日 4:04 下午  @回复  Δ1楼 回复

    全局变量其实就是用来在两段代码之间交换数据用的,除了使用全局变量,还可以使用参数、返回值、回调函数(其实还是参数和返回值)、Windows消息、线程间用Event。

    使用全局变量也有不同的用法,可以简单地定全局变量,也可以向1楼所说的把相关的变量封装为一个结构而改用全局结构变量,复杂点的作法还有使用全局队列、全局查找表等等,一切由你的需求决定。

  2. 爱求索 2015年02月08日 4:05 下午  @回复  Δ2楼 回复

    要去讨论控制生命周期, 全局变量之间的依赖, 多线程冲突这些, 全局变量肯定问题多多, 但是当自己的情况没那么复杂的时候, 这些反而多余. 全局变量成为最好的选择也不是不可能.

  3. 爱求索 2015年02月08日 4:06 下午  @回复  Δ3楼 回复

    要从语法上去除全局变量那还不简单? 把它写到一个函数里就行了:

    int* GetReturnHandShake()
    {
    static int recturnHandShake;
    return &recturnHandShake;
    }

    然后把使用全局变量的地方换成使用这个函数. 但是这样有意思吗?

    另一种好一点的, 把全局变量定义在某一个 .c 文件中, 并定义为 static 的. 然后定义一系列操作这个变量的函数. 头文件里面只有操作函数, 没有变量的声明.

给我留言

留言无头像?