使用變數 為何不建議使用全域性變數

2021-10-25 13:32:37 字數 2417 閱讀 1813

全域性變數(global variables)是指程式中任意地方都能訪問的變數。有時,那些作用域比區域性變數(local variables)更廣的變數也可比作是全域性變數:例如類中可以任意訪問的變數。

個人比較喜歡的說法是,你不知道全域性變數什麼時候被修改了。其產生的後果有:

難以理解

產生歧義

破壞了**封裝

難以測試

int global_variable = 0;

int main()

乍一看認為sum的值應該是6,但結果是12,因為函式inc_global_variable中修改了global_variable的值。

int inc_global_variable(int arg)

在不檢視函式inc_global_variable內部**的情況下,我們是很難理解到底發生了什麼。當乙個函式總是需要檢視它的內部**,這就破壞了建立函式的初衷:封裝**隱藏複雜度。

最後,因為我們不知道全域性變數什麼時候被修改了,這大大增加了**測試難度。作為對比,類似sin,cos這類的三角函式,我們不需要知道內部是如何實現的,只要清楚給定輸入引數就能得到對應的輸出結果。而函式inc_global_variable給定輸入引數後,是仍然無法確定輸出結果的,除非事先確定global_variable的值。換句話說,在不了解**內部實現的情況下,幾乎無法寫測試**。

命名衝突這點應該比較好理解,我們在建立新的變數的時候會盡量避免與之前變數的名稱衝突。乙個區域性函式內部變數的數目也就3~4個的時候,不大會有命名衝突的麻煩。但有了全域性變數之後,情況可能就不一樣了,特別是,沒有限制全域性變數的使用,沒有規範全域性變數的命名,這時候很可能需要我們把之前的**都翻一遍,才能確保避免命名衝突。

有人會說區域性變數是可以覆蓋全域性變數,但這只會產生更多的麻煩。首先特別容易給**閱讀者帶來不必要的歧義。其次對於後來寫**的人,可能錯誤地把全域性變數當做區域性變數使用,或者反過來,把區域性變數當做全域性變數使用。

「別名(aliasing)」指的是兩個或多個名稱指向同乙個變數。

#include int global_variable = 0;

void write_global(int *input_variable)

int main()

第一次顯示的結果是:

input variable is: 2

global variable is: 7

但第二次卻是:

input variable is: 7

global variable is: 7

這是因為,第二次的時候,指標input_variable指向的正是變數global_variable。

在多執行緒的情況下,在修改同乙個全域性變數之前,需要先將其鎖定(locking)。如何鎖定,不同的程式語言語法各有不同,有的簡單有的複雜。資料是何時什麼情況下被修改的變得更加複雜,確保全域性變數前後意義的一致性,顯得特別有挑戰。

乙個檔案的全域性變數的初始化需要依賴另乙個檔案中的全域性變數的初始化。無法確保初始化的順序,就無法確保後續的全域性變數的值。

大家應該有類似的經歷,其他程式中的一段**正好用得著,ctrl-c + ctrl-v之後,當前程式的**就能正常執行了,此時我們就可以愉快的偷個懶了。

但是如果那段**中用了全域性變數,那就比較頭痛了。有些時候,這需要把**重新研究一遍,和再寫一遍無異。

為何要模組化?這是我們處理複雜的大型程式最有效的方法,把它拆解成多個相對簡單小型且互不干擾的模組。互不干擾是保證我們在同一時間只處理其中乙個模組。

全域性變數干擾了模組化,我們不但要關注當前的模組,還要關注所有使用了相同全域性變數的其他模組。

完全不使用全域性變數,這並不怎麼現實。如果將全域性變數推廣至全域性資料,類似資料庫、配置檔案及命名常量(named constants),這些在大多程式應用中都能見到。

書中列出的適合使用全域性變數的情況如下:

先使用區域性變數(local variables),然後是類變數(class variables),最後再嘗試使用全域性變數(global variable)。

比方說,所有全域性變數名以「g_」打頭,g_const_表示全域性命名常量(named constants),g_enum_全域性列舉型別(enumerated types)變數。當然具體情況具體分析,但一定要達成共識。

簡單的說,就是在文件裡把所有的全域性變數在乙個地方列清楚。

這一點比較好理解,說不准,乙個不小心就把中間變數當做全域性變數去使用了。

不建議使用全域性變數,不是說不要使用全域性變數,過猶不及。

使用訪問器(access routines)統一管理全域性變數,是**大全極力推薦的方式。

routine到底是應該翻譯成子程式、函式或是方法一直搞不清楚,好像都沒啥差別。

全域性變數的使用

什麼是全域性變數呢?我們知道,全域性變數是這樣的變數,他們能夠在這個程式中的任何位置都被使用,也就是說,不管是main函式中,還是我們自己寫出來的函式中,都可以無條件的使用他們,雖然這對於我們看來很是方便,但是他隱含的卻違背了結構化的程式設計思想,所以在我們程式化的設計過程中,應該少用全域性變數。在...

matlab 使用全域性變數

全域性變數 global variable 是變數的一種型別,區別於區域性變數。若將乙個變數宣告為全域性變數,則它所佔的記憶體為全域性記憶體,而不是本地工作區記憶體。因此全域性變數就可以被所有工作區訪問,修改。在函式間共用全域性變數 定義兩個函式檔案,setglobalx和getglobalx 設定...

vue cli全域性變數使用

1.函式 vue.prototype.baseurl function 2.變數 vue.prototype.gettitle 新增方法 在vue cli中使用 1直接將上面任乙個 改 放入 src main.js 中,即可定義全部變數。2類似這種配置,可以單獨起乙個配置檔案,1 可以在專案的src...