全局變量/靜態全局變量/局部變量/靜態局部變量的異同點


一、程序的內存分配介紹
  一個由C/C++編譯的程序占用的內存分為以下幾個部分
1、棧區(stack): 由編譯器自動分配釋放,存放函數的參數值,局部變量的值等。其操作方式類似於數據結構中的棧。
2、堆區(heap): 一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收 。注意它與數據結構中的堆是兩回事,分配方式倒是類似於鏈表。
3、全局區(靜態區)(static):全局變量和靜態變量的存儲都是放在靜態區的,初始化的全局變量和靜態變量在一塊區域(.data),未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域(.bss)。  程序結束后由系統釋放。
4、文字常量區:常量字符串就是放在這里的(.rodata)。 程序結束后由系統釋放。
5、程序代碼區:存放函數體的二進制代碼(.text)。
二、程序例子
//main.cpp
int a = 0;           // 全局初始化區
char *p1;           // 全局未初始化區
main()
{
  int b;                  // 棧區
  char s[] = "abc";  // 棧區
  char *p2;            // 棧區
  char *p3 = "123456";     // "123456/0" 在常量區,p3在棧區
  static int c =0;               // 全局(靜態)初始化區
 
  p1 = (char *)malloc(10);
  p2 = (char *)malloc(20); // 分配得來的10和20字節的區域就在堆區
 
  strcpy(p1, "123456");    // "123456/0" 放在常量區,編譯器可能會將它
                                     // 與p3所指向的"123456"優化成一個地方。
三、 問題:static全局變量與普通的全局變量有什么區別?static局部變量和普通局部變量有什么區別?static函數與普通函數有什么區別? 

從作用域看:

  • 全局變量具有全局作用域。全局變量只需在一個源文件中定義,就可以作用於所有的源文件。當然,其他不包括全局變量定義的源文件需要用extern關鍵字再次聲明這個全局變量。      
  •  靜態全局變量也具有全局作用域,他與全局變量的區別在於如果程序包含多個文件的話,他作用於定義它的文件里,不能作用到其他文件里,即被static關鍵字修飾過的變量具有文件作用域。這樣即使兩個不同的源文件都定義了相同的靜態全局變量,他們也是不同的變量。
  • 局部變量具有局部作用域,他是自動對象,他在程序運行期間不是一直存在,而是只在函數執行期間存在,函數的一次調用結束后,變量就被撤銷,其所占用的內存也被收回。         
  • 靜態局部變量也只具有局部作用域。它只被初始化一次,自從第一次初始化直到程序與你新內閣結束都一直存在,他和全局變量的區別在於全局變量對所有的函數都是可見的,而靜態局部變量只對定義自己的函數體始終可見。

從分配內存空間看:

  • 全局變量、靜態局部變量、靜態全局變量都在靜態存儲區分配空間,而局部變量在棧分配空間。
  
 
  1) 全局變量(外部變量)的說明之前再冠以static 就構成了靜態的全局變量。全局變量本身就是靜態存儲方式, 靜態全局變量當然也是靜態存儲方式。 這兩者在存儲方式上並無不同。這兩者的區別在於非靜態全局變量的作用域是整個源程序, 當一個源程序由多個源文件組成時,非靜態的全局變量在各個源文件中都是有效的。 而靜態全局變量則限制了其作用域, 即只在定義該變量的源文件內有效, 在同一源程序的其它源文件中不能使用它。由於靜態全局變量的作用域局限於一個源文件內,只能為該源文件內的函數公用,因此可以避免在其它源文件中引起錯誤。
  2) 從以上分析可以看出, 把局部變量改變為靜態變量后是改變了它的存儲方式即改變了它的生存期。把全局變量改變為靜態變量后是改變了它的作用域,限制了它的使用范圍,因此static這個說明符在不同的地方起的作用是不同的。                   
  3) static函數與普通函數作用域不同,僅在本文件。只在當前源文件中使用的函數應該說明為內部函數(static),內部函數應該在當前源文件中說明和定義。對於可在當前源文件以外使用的函數,應該在一個頭文件中說明,要使用這些函數的源文件要包含這個頭文件   
  綜上所述:
static全局變量與普通的全局變量有什么區別:
static全局變量只初使化一次,防止在其他文件單元中被引用;   
static局部變量和普通局部變量有什么區別:
static局部變量只被初始化一次,下一次依據上一次結果值;   
static函數與普通函數有什么區別:
static函數在內存中只有一份,普通函數在每個被調用中維持一份拷貝

TIPS:

1、若全局變量僅在單個文件中訪問,則可以講這個變量修改為靜態全局變量。

2、若全局變量僅在單個函數中使用,則可以將這個變量修改為該函數的靜態局部變量。

3、全局變量、靜態局部變量、靜態全局變量都存放在靜態數據存儲區。

4、靜態變量會被放在程序的靜態數據存儲區里,這樣可以在下一次調用的時候還可以保持原來的賦值。這一點是他與堆棧變量和堆變量的區別

5、變量用static告知編譯器,自己僅僅在變量的作用域范圍內可見。這一點是他與全局變量的區別。

6、函數中必須要使用static變量的情況:當某函數的返回值為指針類型時,則必須是static的局部變量的地址作為返回值,若為auto類型,則返回為錯指針。

7、全局變量作用域是跨越多個源程序的,因此全局變量不能重名。靜態變量作用域是位於單個源程序內,多個源程序可以有同名的全局靜態變量。靜態局部變量可以和靜態全局變量重名,前者會將后者屏蔽掉。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM