靜態全域性變數和全域性變數的區別(轉)
轉自: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儲存型別。