談到全局變量、局部變量和靜態(tài)變量,就涉及到兩個(gè)概念:作用域和生存期。
這是兩個(gè)完全不同的概念,雖然很多時(shí)候相互關(guān)聯(lián)。作用域是作用在空間上的,比如一個(gè)變量在代碼的哪些行能訪(fǎng)問(wèn),哪些行不能訪(fǎng)問(wèn)。而生存期是作用在時(shí)間上的,比如一個(gè)變量的值在函數(shù)返回后是否失效。
全局變量
全局變量比較好理解,如果一個(gè)變量是全局變量,那么程序中的所有代碼都可以訪(fǎng)問(wèn)到這個(gè)變量(除非存在同名的局部變量或者靜態(tài)變量)。全局變量用 global 定義。
看一個(gè)例子。
a := 1
global b := 2
c := 3
fun()
fun()
{
; a 不是全局變量,訪(fǎng)問(wèn)不了,彈出空字符串
MsgBox, % a
; b 是全局變量,彈出 2
MsgBox, % b
; 在函數(shù)里也可以將 c 變成全局變量
global c
; 彈出 3
MsgBox, % c
}
注意代碼里的 a 并不是全局變量,雖然它的作用域要比函數(shù)里的局部變量要大,在所有文件的函數(shù)外都可以訪(fǎng)問(wèn),但在函數(shù)內(nèi)它是不能被訪(fǎng)問(wèn)到的,這算是一個(gè)特例。
局部變量
在函數(shù)里使用的變量通常是局部變量。
fun()
; a 并不是全局變量,彈出空字符串
MsgBox, % a
; b 是全局變量,彈出 2
MsgBox, % b
fun()
{
a := 1
global b := 2
}
注意這里 b 是在函數(shù)里定義的全局變量,但不管是在什么地方定義的,在其他地方都可以訪(fǎng)問(wèn)到。
靜態(tài)變量
全局變量和局部變量的作用域和生存期都不一樣。全局變量的作用域和生存期都是全局的,局部變量的作用域是在函數(shù)內(nèi)部,生存期是從函數(shù)開(kāi)始執(zhí)行到函數(shù)返回。
但還有一種比較特別的變量是靜態(tài)變量。
; 彈出 1 1
fun()
; 彈出 1 2
fun()
fun()
{
a := 1
static b := 1
MsgBox, % a " " b
a++
b++
}
a 就是普通的局部變量,因?yàn)槊看螆?zhí)行 a 都會(huì)被初始化為 1,所以?xún)纱芜\(yùn)行 fun 函數(shù)時(shí) a 的值都是 1。但 b 是一個(gè)靜態(tài)變量(使用 static 定義)。靜態(tài)變量的作用域和局部變量一樣,只能在函數(shù)內(nèi)訪(fǎng)問(wèn)。但生存期和全局變量一樣,也就是說(shuō)一個(gè)靜態(tài)變量定義后,它的值會(huì)一直有效,即使函數(shù)已經(jīng)返回了。所有第二次運(yùn)行 fun 函數(shù)后,b 的值已經(jīng)是 2 了。
使用場(chǎng)景
那么什么分別在什么情況下使用三者呢?
沒(méi)有特殊需求的場(chǎng)景,都應(yīng)該使用局部變量,這也是默認(rèn)的情況。
如果一個(gè)變量是需要全局有效的,那么使用全局變量。但全局變量會(huì)導(dǎo)致代碼的耦合度比較高,不方便維護(hù),所以盡量少用。有些看似需要使用全局變量的場(chǎng)景,其實(shí)使用函數(shù)的參數(shù)傳遞更合理。
如果某個(gè)局部變量需要只初始化一次(一般情況是因?yàn)槌跏蓟虚_(kāi)銷(xiāo),這是主要的場(chǎng)景),或者需要保留上次運(yùn)行的結(jié)果(這會(huì)導(dǎo)致代碼容易滋生 bug,并且難于測(cè)試,盡量少用),那么需要將這個(gè)局部變量修改成靜態(tài)變量。
除了全局變量、局部變量、靜態(tài)變量,還有在類(lèi)中的變量,這個(gè)我會(huì)在類(lèi)中單獨(dú)講。
付費(fèi)解決 Windows、Linux、Shell、C、C++、AHK、Python、JavaScript、Lua 等領(lǐng)域相關(guān)問(wèn)題,靈活定價(jià),歡迎咨詢(xún),微信 ly50247。