全局变量

(重定向自全域變數

程序设计中,全局变量是在所有作用域都可访问的变量,与之对应的是局部变量

通常,使用不必要的全局变量被认为是坏习惯,这正是由于全局变量的非局部性:全局变量可能被从任何地方修改(除非位于保护内存中),也可能被任何地方所依赖。于是全局变量便拥有了建立相互依存关系的无限可能,而互相依存关系的建立会使得复杂度增加,参见远隔作用(Action at distance)。然而,在少数情况下是适合使用全局变量的。例如,可以通过全局变量的使用来避免常用变量在一系列函数间的频繁传递。

例子

C++语言中全局变量的例子:

#include <cstdio>

int global = 3; // 定义全局变量 global

static void ChangeGlobal(void)
{
   global = 5; // 从函数中引用全局变量
}

int main(void)
{
   std::printf("%d\n", global); // 还是从函数中引用全局变量
   ChangeGlobal();
   std::printf("%d\n", global);
}

因为变量是全局的,所以就没有必要为了在 main 以外的函数中使用而作为参数传递。全局变量属于程序中的所有函数。

输出应该是:

3
5

全局变量的使用使得软件更加难以阅读和理解。因为程序中任何地方的代码都可能随时修改这个变量的值,于是理解这个变量可能就意味着要理解整个程序的很大部分。

某些语言(比如C#Java)中没有全局变量。Java 中,所有非局部变量都是类的字段,于是所有变量就都在类和方法的作用域中了。

需要指出的是,C语言不存在真正意义上的“全局变量”。被习惯性误称为“全局变量”的,一般是文件作用域对象。ANSI C/ISO C也没有这种提法。 C语言中所谓“全局变量”的例子:

/* 注意这个例子是有问题的。
   global 并不是全局变量,因为它并不是“所有作用域均可见”。
   global 是C语言中的文件作用域变量,作用域从声明开始一直到文件末尾。*/
#include <stdio.h>

int global = 3; /* 这是“全局变量” */

static void ChangeGlobal(void)
{
   global = 5; /* 从函数中引用“全局变量” */
}

int main(void)
{
   printf("%d\n", global); /* 还是从函数中引用“全局变量” */
   ChangeGlobal();
   printf("%d\n", global);
   return 0;
}

参见

参考资料

  • William Wulf and Mary Shaw, “Global Variable Considered Harmful”, ACM SIGPLAN Notices, volume 8, issue 2, 1973 February, pp. 28–34.