static作用:静态变量的生存周期和作用域
首先要理解生存周期與作用域的區(qū)別: 
 生存周期: 變量從定義到銷毀的時間范圍。存放在全局數(shù)據(jù)區(qū)的變量的生存周期存在于整個程序運行期間,而存放在棧中的數(shù)據(jù)則隨著函數(shù)等的作用域結(jié)束導致出棧而銷毀,除了靜態(tài)變量之外的局部變量都存放于棧中。 
 作用域: 變量的可見代碼域(塊作用域,函數(shù)作用域,類作用域,程序全局作用域)。
static變量是指靜態(tài)的變量,不管是在全局還是局部聲明的static變量都存放于程序的全局變量區(qū)域,所以它的生命周期是從程序開始到程序結(jié)束。但是static變量的作用域并不等同于它的生存周期,它的作用域決定于它被定義的位置。可以認為static變量的作用域<=生存周期。
舉一個局部聲明的例子。在函數(shù)test中聲明靜態(tài)變量i: 
 void test() 
 { 
 int m=3; 
 static int i=5; 
 } 
 局部變量m存放在棧中,當test函數(shù)結(jié)束,m將被銷毀;靜態(tài)變量i不存放在棧中,而是存放于程序的全局變量區(qū)域,因此隨著函數(shù)test的結(jié)束,它并不隨著出棧操作而被銷毀,它的生存周期存在于程序的整個運行期;然而m和i的作用域都僅存在于test函數(shù)中它們的定義之后,即test調(diào)用結(jié)束之后,m和i就不再可用,但是i仍存在于內(nèi)存之中。
再舉一個全局聲明的例子。在文件A 中定義靜態(tài)變量j: 
 int n=3; //默認為extern 
 static int j=5; //聲明為static 
 全局變量和靜態(tài)變量j都存放于程序的全局數(shù)據(jù)區(qū)域,它們的生存周期都是程序的整個運行期,但是n的作用域為全局作用域,可以通過extern在其他文件中使用,而j只能在文件A中使用,例如在文件B中: 
 extern int n; //ok 
 extern int j; //error: j在文件B中不可見 
 int a=n;//ok:但這里有個初始化先后的問題,具體參見參考一 
 int b=j;//error 
 也就是說,在聲明全局的static變量時,static沒有改變它的生存周期,也即存儲位置(因為全局變量本來就存儲在全局數(shù)據(jù)域),而是將變量的作用域限制在當前文件中。
中興通訊2012校招筆試題的一道問答題: 
 1. static全局變量與普通的全局變量有什么區(qū)別 ? 
  全局變量(外部變量)的說明之前再冠以static 就構(gòu)成了靜態(tài)的全局變量。 
   全局變量本身就是靜態(tài)存儲方式, 靜態(tài)全局變量當然也是靜態(tài)存儲方式。 這兩者在存儲方式上并無不同。 
   這兩者的區(qū)別在于非靜態(tài)全局變量的作用域是整個源程序, 當一個源程序由多個源文件組成時,非靜態(tài)的全局變量在各個源文件中都是有效的。 而靜態(tài)全局變量則限制了其作用域, 即只在定義該變量的源文件內(nèi)有效, 在同一源程序的其它源文件中不能使用它。由于靜態(tài)全局變量的作用域局限于一個源文件內(nèi),只能為該源文件內(nèi)的函數(shù)公用,因此可以避免在其它源文件中引起錯誤。 
 static全局變量只初使化一次,防止在其他文件單元中被引用;   
 2. static局部變量和普通局部變量有什么區(qū)別 ? 
   把局部變量改變?yōu)殪o態(tài)變量后是改變了它的存儲方式即改變了它的生存期。把全局變量改變?yōu)殪o態(tài)變量后是改變了它的作用域,限制了它的使用范圍。 
   static局部變量只被初始化一次,下一次依據(jù)上一次結(jié)果值;   
 3. static函數(shù)與普通函數(shù)有什么區(qū)別? 
    static函數(shù)與普通函數(shù)作用域不同,僅在本文件。只在當前源文件中使用的函數(shù)應該說明為內(nèi)部函數(shù)(static修飾的函數(shù)),內(nèi)部函數(shù)應該在當前源文件中說明和定義。對于可在當前源文件以外使用的函數(shù),應該在一個頭文件中說明,要使用這些函數(shù)的源文件要包含這個頭文件. 
 static函數(shù)在內(nèi)存中只有一份,普通函數(shù)在每個被調(diào)用中維持一份拷貝
P.S. 
 C程序一直由下列部分組成: 
 1)正文段(代碼段)——CPU執(zhí)行的機器指令部分;一個程序只有一個副本;只讀,防止程序由于意外事故而修改自身指令; 
 2)初始化數(shù)據(jù)段(數(shù)據(jù)段)——在程序中所有賦了初值的全局變量,存放在這里。 
 3)非初始化數(shù)據(jù)段(bss段)——在程序中沒有初始化的全局變量;內(nèi)核將此段初始化為0。(這就是為什么全局內(nèi)置類型變量會初始化,而局部變量就為未初始化的未知值) 
 4)棧——增長方向:自頂向下增長;自動變量以及每次函數(shù)調(diào)用時所需要保存的信息(返回地址;環(huán)境信息)。 
 5)堆——動態(tài)存儲分。 
 程序在內(nèi)存中申請了代碼段,全局數(shù)據(jù)段(初始化和未初始化),棧和堆:程序代碼放于代碼段,全局變量和靜態(tài)變量存放在全局數(shù)據(jù)段中,一直存在直到程序結(jié)束,而局部變量都放于臨時的棧中,隨著作用域的結(jié)束隨著出棧操作而銷毀。malloc和new出來的內(nèi)存不屬于上面提到的程序申請的內(nèi)存中,而是在系統(tǒng)中申請到的內(nèi)存,所以如果在程序中沒有明確free和delete的話,程序結(jié)束后該內(nèi)存仍不會被釋放,造成內(nèi)存泄漏。例如: 
 int test() 
 { 
 int * p=new int(3); 
 } 
 則test函數(shù)結(jié)束后,p指針本身被銷毀,因為它是存在于函數(shù)棧中的局部變量,而p指向的int整型內(nèi)容仍存在于內(nèi)容堆中,沒有被釋放,造成內(nèi)存泄漏。 
 詳細內(nèi)存使用和參考http://blog.csdn.net/cc198877/article/details/8849694
參考 
http://www.cnblogs.com/jerry19880126/archive/2013/03/09/2951186.html 
http://www.cnblogs.com/jerry19880126/archive/2012/12/22/2829394.html 
http://www.cnblogs.com/stoneJin/archive/2011/09/21/2183313.html 
http://bbs.csdn.net/topics/350238100
轉(zhuǎn)載于:https://www.cnblogs.com/bigclould/p/9322248.html
總結(jié)
以上是生活随笔為你收集整理的static作用:静态变量的生存周期和作用域的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: nupkg 本地安装_使用Nuget安装
- 下一篇: C#开发WPF/Silverlight动
