1. 程式人生 > 其它 >靜態全域性變數和全域性變數的區別(轉)

靜態全域性變數和全域性變數的區別(轉)

轉自:https://blog.csdn.net/zzhays/article/details/8011645

貌似很多人區分不了這二者之間的區別,表面上看都是作用在整個文件,而且任何一個地方改變都會影響其值的改變。但是細分就會發現其區別:

//Example 1 

 #include <iostream.h>

  void fn();  

static int n; //定義靜態全域性變數 

 void main() 

 {
n=20;   cout<<n<<endl;   fn(); 

 } 

 void fn() { n++;  cout<<n<<endl;  }


靜態全域性變數有以下特點:  該變數在全域性資料區分配記憶體;未經初始化的靜態全域性變數會被程式自動初始化為0(在函式體內宣告的自動變數的值是隨機的,除非它被顯式初始化,而在函式體外被宣告的自動變數也會被初始化為0); 靜態全域性變數在宣告它的整個檔案都是可見的,而在檔案之外是不可見的; 靜態變數都在全域性資料區分配記憶體,包括後面將要提到的靜態區域性變數。對於一個完整的程式,在記憶體中的分佈情況如下圖:

程式碼區 //low address  

全域性資料區
堆區
棧區 //high address  

一般程式把新產生的動態資料存放在堆區,函式內部的自動變數存放在棧區。自動變數一般會隨著函式的退出而釋放空間,靜態資料(即使是函式內部的靜 態區域性變數)也存放在全域性資料區。全域性資料區的資料並不會因為函式的退出而釋放空間。細心的讀者可能會發現,Example 1中的程式碼中將   static int n; //定義靜態全域性變數   改為   int n; //定義全域性變數   程式照樣正常執行。  的確,定義全域性變數就可以實現變數在檔案中的共享,但定義靜態全域性變數還有以下好處:  靜態全域性變數不能被其它檔案所用;   其它檔案中可以定義相同名字的變數,不會發生衝突;   您可以將上述示例程式碼改為如下: 

 //Example 2 //File1  

#include <iostream.h>

  void fn();

  static int n; //定義靜態全域性變數 

 void main()

{ n=20;   cout<<n<<endl;   fn();  }  

//File2

#include <iostream.h> 

 extern int n; 

 void fn()

  { n++;   cout<<n<<endl;  }  

 編譯並執行Example 2,您就會發現上述程式碼可以分別通過編譯,但執行時出現錯誤。

試著將   static int n; //定義靜態全域性變數   改為   int n;

//定義全域性變數   再次編譯執行程式,

細心體會全域性變數和靜態全域性變數的區別。

注意:全域性變數和全域性靜態變數的區別  

1)全域性變數是不顯式用static修飾的全域性變數,但全域性變數預設是動態的,作用域是整個工程,在一個檔案內定義的全域性變數,在另一個檔案中,通過extern 全域性變數名的宣告,就可以使用全域性變數。  

2)全域性靜態變數是顯式用static修飾的全域性變數,作用域是宣告此變數所在的檔案,其他的檔案即使用extern宣告也不能使用。

3)檔案作用域下宣告的const的常量預設為static儲存型別。