全域變數

程式設計中,全域變數是在所有作用域都可訪問的變數,與之對應的是局部變數

通常,使用不必要的全域變數被認為是壞習慣,這正是由於全域變數的非局部性:全域變數可能被從任何地方修改(除非位於保護主記憶體中),也可能被任何地方所依賴。於是全域變數便擁有了建立相互依存關係的無限可能,而互相依存關係的建立會使得複雜度增加,參見遠隔作用(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.