轉自: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存儲類型。