`

全局变量是“万恶之源”,慎用

阅读更多
正在看一个老项目的代码,满篇都是全局变量,整个逻辑真的是“意大利面条”,不晓得这些全局变量什么时候被改变,什么时候被调用,恨透了全局变量和传递引用(传递引用适可而止也就罢了,传递个4,5层,鬼知道变量什么时候被改变)。

下面是一些对全局变量的观点,基本上一致,全局变量用好省事,滥用麻烦,所以慎用。

TBOB:
不止一次地看到人们在抱怨,全局变量是罪恶之源,根本就不应该使用它们。但是我不认为这个结论是显而易见正确的。我希望能听到一次有关全局变量的严肃认真的讨论。论坛中的朋友们很多都提到了他们都正在编程中使用全局变量。
先从全局变量的有点谈起。一般来说,全局变量是公认的在各个VI之间传递数据的有效方法,比起其它方式的全局变量(个人意见)更容易管理,因为假如我们使用了一个簇作为全局数据,我们没有办法确定在何处使用了它们,可能需要自己创建一个文件记录它们使用的位置。但是全局变量则不然,通过全局变量的右键快捷菜单,我们可以很容找到引用全局变量的位置。

使用全局变量有两个不利之处,其一,引用全局变量需要创建数据的拷贝,这可能会导致潜在的竞争条件或者导致数据的丢失。其二,使用全局变量会中断数据流程。
所以,我对那些反对使用全局变量的人士提出一个问题---你们在应用全局变量时考虑了全局变量是否有效的问题了吗?
如果对全局变量只有一个写入者,而有多处读取者,您仅仅关心变量的最新写入值的情况下,您怎么能断定不能使用全局变量呢?
------------------------------------------------------------------------------------------------------------------
Darren:
全局变量在某些情况下是非常好用的。如果我有一些静态数据,这些静态数据必须在多个VI中共享,这种情况下,我会使用全局变量存储这些静态数据。(所谓静态数据就是不需要改变的数据,常量)。最常见的例子是需要给用户提示的文本字符串。如果我有一个非常复杂的GUI,需要在很多地方向用户提示文本信息。我会创建一个全局变量VI,把这些字符串创建为全局变量,并且按照字母顺序排序(通过设置TAB ORDER)。这样我们需要在程序框图中使用全局变量时,直接拖入并选择我们需要的。这种方法可以很容易使我们的应用程序本地化,因为所有的显示字符串集中在一个VI之中,而不是散布在各个VI之中,很容易集中处理。
我另外一次使用全局变量是在一个子面板应用中,因为我的子面板中的VI不需要和主VI交换信息,所以我将子面板VI中的数据写入全局变量,供应用程序其它部分读取。因为不需要同步化以及只有子面板中的VI写入数据,保证了只有一个写入者,这恰恰是全局变量的最佳工作方式。
------------------------------------------------------------------------------------------------------------------
TBOB:
很高兴能看到同人谈及如何恰当地使用全局变量,而不是简单地说完全不要使用全局变量。我们更应该强调如何恰当地使用全局变量,帮助人们了解数据竞争是如何产生的,以及如何避免竞争情况出现。

我大多数使用全局变量时,是把全局变量作为常量来使用的,比如保存一个GPIB的地址。它们一旦创建后就永远不会再次写入更改,这种情况下,绝对不会出现数据竞争的情况。或者在生产消费者模式中,生产者写入全局变量,而消费者读取全局变量。这种情况下,读的时机是非常重要的。我使消费者不断查询全局变量,是否和原来的值发生变化。换句话说,消费者在数据更新之前可能读取了两次,当然并不很理想。
对于局部变量也是如此,总有它们合适使用的场合,但是必须小心可能会导致的问题。教会人们发现问题和解决问题好于仅仅说避免使用它们。
------------------------------------------------------------------------------------------------------------------
Jasonhill:
我也经常看到要求禁止使用全局变量,在合适的条件下,使用全局变量还是非常有用的。但是程序员还是会不自觉地倾向于滥用它们,任何变量(全局变量、局部变量、LV2全局变量)在使用时需要格外小心,“连线”还是最安全的。
我非常讨厌上下或者左右堆积大量的控件,在程序框图中多达20几个层叠顺序结构中,到处散布一些全局变量或者局部变量。
至于你提及的生产者消费者模式,我还是愿意使用队列来完成,使用队列可以使我们不需要考虑读的时机问题。
------------------------------------------------------------------------------------------------------------------
TBOB
在生产者消费者模式中,使用队列(我也倾向于使用队列,而不是变量)同样存在问题。消费者可能运行速度高于消费者,此时可能读回空数据,必须在编程中检查是否是否读回空数据。
------------------------------------------------------------------------------------------------------------------
TST:
在生产消费者模式使用队列时,我愿意使用超时的默认值-1,这意味着消费者在没有数据时不会执行一个循环,也不需要检查超时是否发生了。
------------------------------------------------------------------------------------------------------------------
TITOU:
真是个好题目!
全局变量是魔鬼吗?------我愿意这样回答:不是,只要你遵循了全局变量的工作规则。
我经常建议避免使用全局变量,但是的确在特定的场合,我还是会使用全局变量,因为使用全局变量的确非常方便。
使用但不要滥用------------------------------------------------------------------------------------------------------------------
ROBERT:
即使在基于文本的编程语言中,采用封装和抽象本身就倾向于不使用全局变量。理想的结构应该是这样的,如果函数需要一个变量,必须从函数的调用者哪里接收这个变量。尽管如此,即使在这样的编程环境中,还是需要有限度的和合理的利用全局变量。正如上面的帖子中指出的那样,一个写入者,多个读取者。亦或需要在整个程序应用,但是不需要改变的场合。
我经常采样下面的方式。在程序启动时,先运行一个配置函数或者“参数设置”函数,此时没有其它的进程工作,数据采集也尚未进行。此时为程序的其它部分创建全局变量是合理的。
------------------------------------------------------------------------------------------------------------------
KEVIN:
我在程序开发时,习惯于在多个消费者情况下使用“通告”。通常情况下,只有一个生产者。但是像全局变量情况,可能会有几个“潜在”的生产者。
对于使用通告,消费者可以进行选择。通告可以不管消费这是否已经消费了先前的数据,随时查询最新的数据,这类似于全局变量。通告也可以一直等待,直至有最新更新的数据,避免不断的轮询数据,加重CPU的负担,这个是全局变量无法实现的。
-----------------------------------------------------------------------------------------------------------------
BEN:
很抱歉没能早点参与这个话题的讨论。我并非求全责备,但是全局变量存在下列主要问题:
1、数据拷贝
2、利用线程
3、对于一个写入者,多个读取者,OK.但是这要求开发者必须确认只有唯一一个写入者。这对一个拥有800多个VI,有些是动态载入的情况下,是很难做到的。
4、灵活性 。如果你使用一个LV2型全局变量,需要的情况下,你可以很安全地添加新的新的写入者。在编写大型应用时,这的确是令人头疼的问题。
5、性能。LV2全局变量可以很容易重用缓存,全局变量不行。
-----------------------------------------------------------------------------------------------------------------
RAY:
我同意大家的看法。我通常用全局变量保持静态数据,比如IP地址。
分享到:
评论

相关推荐

    定义全局变量 变量 全局

    在MFC(Microsoft Foundation Classes)框架中,全局变量和函数的使用与标准C++有所不同,因为MFC工程通常由多个文件组成,需要一种方法来在这些文件之间共享数据和功能。这里将介绍两种在MFC工程中定义全局变量和...

    labview功能性全局变量的详细使用

    LabVIEW功能性全局变量是开发大型、复杂应用时非常重要的数据通信工具。它们允许在不同的VI(虚拟仪器)之间共享数据,解决了局部变量在多线程环境下可能出现的数据竞争问题。本篇将详细介绍LabVIEW功能性全局变量的...

    C++中类使用全局变量

    全局变量`a`在此处的作用是为`printfl()`函数提供打印的数据源。 ```cpp class date { public: void printfl(); }; ``` `date`类中只有一个公共成员函数`printfl()`,没有实例数据成员。`printfl()`的作用是打印...

    C/C++ 跨文件共享全局变量Demo

    在C/C++编程中,跨文件共享全局变量是一项常见的需求,尤其在大型项目或模块化设计中。全局变量能够在程序的任何地方被访问,而跨文件共享则意味着这些变量可以在不同的源文件之间传递数据。本Demo将展示如何在C/C++...

    C++全局变量初始化的一点总结

    C++中的全局变量初始化是一个重要的话题,涉及到程序的正确性和可预测性。全局变量,即具有静态存储期的变量,其生命周期始于程序开始,终于程序结束。本文将深入探讨全局变量初始化的时机、方式以及一些处理特殊...

    易语言源码易语言汇编设置全局变量源码.rar

    全局变量是在整个程序范围内都可访问的变量,与局部变量(仅限于函数或模块内部)不同,全局变量的生命周期贯穿整个程序的执行过程。在易语言中设置全局变量,可以使用“定义全局变量”命令,指定变量名和类型。全局...

    VB 全局变量举例

    在VB(Visual Basic)编程语言中,全局变量是一种在整个程序范围内都可以访问的变量。与局部变量(仅在特定函数或子程序中有效)不同,全局变量可以在任何模块、窗体或标准模块中被调用,这使得它们在存储和传递数据...

    QT 使用全局变量的方法 - 郭小郭的专栏 - CSDN博客1

    QT 使用全局变量的方法 在QT编程中,全局变量的使用有时是必要的,特别是在需要在不同类或函数之间共享数据的情况下。然而,全局变量的使用应该谨慎,因为它们可能破坏封装性和增加代码的复杂性。以下是两种在QT中...

    VC中的全局变量.doc

    - **慎用全局变量**:尽量避免在非必要的场景下使用全局变量,尤其是对于大型项目,全局变量可能导致难以追踪的错误和难以维护的代码。 - **局部化**:若必须使用全局变量,考虑将其封装在类或结构体中,通过方法...

    微信小程序全局变量改变监听的实现方法

    当时想到的就是使用全局变量,在 app.js 中定义好全局变量,点击组件页面时就修改全局变量的值,父页面同样使用全局变量的值,这样一来就可以动态打开/关闭弹出层且传递值了。 下面先看看 app.js 中怎么定义的: ...

    C语言面试题大汇总之华为面试题:1、局部变量能否和全局变量重名;2、如何引用一个已经定义过的全局变量;3、全局变量可不可以定义在可被多个.C文件包含的头文件中 为什么;4、语句for( ;1 ;)有什么问题 它是什么意思……

    本文总结了C语言面试题大汇总之华为面试题,涵盖了局部变量、全局变量、extern关键字、for循环、while循环、静态变量、静态函数、内存分配等知识点。 一、局部变量和全局变量 局部变量可以与全局变量同名,在函数...

    采用全局变量方式实现多线程的通信

    全局变量作为一种简单的方式被用于实现线程间的通信,尤其是在MFC(Microsoft Foundation Classes)框架下。下面我们将深入探讨如何利用全局变量进行多线程通信以及涉及的相关知识点。 首先,我们要理解什么是全局...

    在C/C++项目中使用全局变量的方法

    ### 在C/C++项目中使用全局变量的方法 #### 概述 在开发C/C++项目时,有时需要在多个源文件之间共享数据或状态信息。全局变量作为一种简单且直观的数据共享方式,在某些场景下非常实用。然而,不当的使用全局变量...

    Discuz_$_G全局变量

    Discuz是一款广泛应用于社区论坛建设的开源软件,其核心组件之一是$_G全局变量。这个全局变量在Discuz系统中扮演着至关重要的角色,它存储了论坛运行过程中的各种信息,便于开发者在模板和插件开发中快速获取和操作...

    altium designer 过程中全局变量的编写

    Altium Designer是一款强大的电子设计自动化(EDA)软件,用于电路板设计和布局。在使用Altium Designer进行PCB...因此,对于Altium Designer的用户来说,理解和运用全局变量及全局编辑是提升工作效率的关键技能之一。

    全局变量的使用

    全局变量在程序设计中扮演着重要的角色,它们可以在程序的不同函数之间共享数据,尤其是在大型项目中,当多个函数需要访问同一份数据时。全局变量的生命周期始于程序的启动,结束于程序的终止,这意味着在整个程序...

    局部变量和全局变量总汇

    - **作用域不同**:普通全局变量在整个源程序中都是有效的,而`static`全局变量只在其定义所在的源文件内有效。 - **生命周期不同**:普通全局变量在整个程序运行期间都存在,而`static`全局变量仅在其定义的...

    labview局部变量与全局变量

    本压缩包包含有关LabVIEW局部变量和全局变量的重要知识资源,非常适合想要深入理解和掌握这两种变量用法的学习者。 **局部变量(Local Variables)** 在LabVIEW中,局部变量是在函数或子VI内部定义的,它们的作用...

Global site tag (gtag.js) - Google Analytics