關于局部變量、全局變量與靜態(tài)全局變量和靜態(tài)局部變量的比較與分析和拓展:
首先要明白的是局部變量與其它三個有本質區(qū)別。
局部變量,定義在函數(shù)內,作用域為定義位置,到所在大括號結束。 每次執(zhí)行到定義語句的時候,系統(tǒng)為該變量分配內存,當作用域結束后,內存被釋放。
而另外三個,都是在系統(tǒng)運行時就分配內存,在運行過程中都不會釋放,直到程序結束。
也就是說,局部變量和其它三個,最明顯的區(qū)別:
1 生命周期不同
2 分配時間不同
3 分配位置不同。
而另外三個,在這幾項上是相同的,之間的區(qū)別在于作用域。
全局變量,作用域為整個項目,不管在哪個文件中,只要聲明后都可以使用,當然,其他不包含全局變量定義的源文件需要用extern 關鍵字再次聲明這個全局變量。
靜態(tài)全局變量也具有全局作用域,他與全局變量的區(qū)別在于如果程序包含多個文件的話,他作用于定義它的文件里,不能作用到其他文件里,即被static關鍵字修飾過的變量具有文件作用域。這樣即使兩個不同的源文件都定義了相同的靜態(tài)全局變量,他們也是不同的變量。
而靜態(tài)局部變量,作用域與普通局部變量一樣,都是定義位置到所在大括號結束。靜態(tài)局部變量具有局部作用域,它只被初始化一次,自從第一次被初始化直到程序運行結束都一直存在,他和全局變量的區(qū)別在于全局變量對所有的函數(shù)都是可見的,而靜態(tài)局部變量只對定義自己的函數(shù)體始終可見。
需要注意的是:
1>全局變量,靜態(tài)局部變量,靜態(tài)全局變量都在靜態(tài)存儲區(qū)分配空間,而局部變量在棧里分配空間。
2>全局變量本身就是靜態(tài)存儲方式, 靜態(tài)全局變量當然也是靜態(tài)存儲方式。這兩者在存儲方式上并無不同。這兩者的區(qū)別雖在于非靜態(tài)全局變量的作用域是整個源程序,當一個源程序由多個源文件組成時,非靜態(tài)的全局變量在各個源文件中都是有效的。而靜態(tài)全局變量則限制了其作用域,即只在定義該變量的源文件內有效,在同一源程序的其它源文件中不能使用它。由于靜態(tài)全局變量的作用域局限于一個源文件內,只能為該源文件內的函數(shù)公用,因此可以避免在其它源文件中引起錯誤。
注釋:static修飾局部變量說明
1)靜態(tài)局部變量屬于靜態(tài)存儲類別,在靜態(tài)存儲區(qū)分配存儲單元。 在程序整個運行期間都不釋放。自動變量(即動態(tài)局部變量)屬于動態(tài)存儲類別,占動態(tài)存儲區(qū)空間,函數(shù)調用之后即 釋放。
2)對靜態(tài)局部變量,是在編譯時候賦初值的,即只付出至一次,在程序運行時它已由初值。以 后每次調用的時候不再重新賦初值而只是保留上次函數(shù)調用結束時的值。而對自動變量賦初值,不是在編譯的時候進行的,而是在函數(shù)調用時進行。每調用一次函數(shù),重新給一個初值。 相當于執(zhí)行一次賦值語句。靜態(tài)變量會被放在程序的靜態(tài)數(shù)據(jù)存儲區(qū)里,這樣可以在下一次調用的時候還可以保持原來的賦值。這一點是他與堆棧變量和堆變量的區(qū)別
3)如在定義局部變量時不賦初值的話,則編譯器對靜態(tài)變量默認賦值為0(整型)或者空字符(字符型) ,對動態(tài)變量只分配內存空間,并不會賦默認值,所以里面的值是隨機的。
4)靜態(tài)局部變量在函數(shù)調用結束之后仍然是存在的,但是作用域不變,其他函數(shù)依然不能引用。
關于static功能的拓展:
1.static與 extern對函數(shù)的作用:
函數(shù)的本質是全局的,寫函數(shù)就是用來調用的,但是有些時候不想讓其他文件訪問指定函數(shù)。
根據(jù)函數(shù)能否被其他文件調用,將函數(shù)分為了內部函數(shù)和外部函數(shù)。
內部函數(shù):只能被本文件中其他函數(shù)所調用,成為內部函數(shù)。在定義函數(shù)的時候使用static修飾就可以了。
外部函數(shù):能被其他文件訪問,定義的時候在最左邊加關鍵字extern顯示表示為外部函數(shù),不加則表示隱含的extern。
2.函數(shù)中必須要使用static變量的情況:當某函數(shù)的返回值為指針類型時,則必須是static的局部變量的地址作為返回值,若為auto類型(參考//注釋:),則返回為其指針。局部變量在函數(shù)調用后就銷毀了,雖然地址還在,但是那個地址存的數(shù)據(jù)是無法保證安全性的,因此如果想指向被調函數(shù)中的參數(shù),最好將其定義為靜態(tài)的~
//注釋:
auto在函數(shù)中的局部變量,如果不專門聲明為static存儲類別,都是動態(tài)分配存儲空間的,數(shù)據(jù)存儲在動態(tài)存儲區(qū)中。函數(shù)中的形參和函數(shù)中的變量都是這種類型的。在調用該函數(shù)的時候系統(tǒng)會給分配內存空間,函數(shù)調用完畢之后,自動釋放這些存儲空間。因此這類局部變量稱為自動變量。
函數(shù)中,定義auto int a = 10,跟int a = 10等價Register
關鍵字regiter請求編譯器盡可能的將變量存在CPU的寄存器中。有以下幾點注意的地方。
register變量必須是能被CPU寄存器所接受的類型,這通常意味著register變量必須是一個單個的值,并且其長度應小于或等于整型的長度。但是,有些機器的寄存器也能存放浮點數(shù)。
register變量可能不存放在內存中,所以不能用取址符運算符“& ”。 只有局部變量和形參可以作為register變量,全局變量不行。 靜態(tài)變量不能定義為register。