普通區域性變數、普通全域性變數、static區域性變數、static全域性變數
一、普通全域性變數和普通區域性變數的關係
通常情況下,如果有兩個同名變數,一個是普通全域性變數,另一個是普通區域性變數,那麼區域性變數在其作用域內具有較高的優先權,它將遮蔽全域性變數。
#include <stdio.h> #include<iostream> int count = 1; using namespace std; int fun(void) { int count = 10; return count; } int main(void) { cout<<fun()<<endl; return 0; }
如果全域性變數定義在某個定義函式之後,並且定義函式中有相應的全域性變數,此時程式會報錯。
如下程式所示:
#include <stdio.h>
#include<iostream>
using namespace std;
int fun(void)
{
return count;
}
int count = 1;
int main(void)
{
cout<<"fun()="<<fun()<<endl;
return 0;
}
如果我們希望在區域性變數的作用域內使用同名的全域性變數,那麼可以在該變數的前面加上“::
#include<iostream>
using namespace std;
int count = 10;//全域性變數定義
int main(void)
{
int count;//區域性變數的定義
count = 100;
cout <<"local value="<<count<<endl;
cout <<"global value="<<::count<<endl;
return 0;
}
二、static區域性變數與普通區域性變數的區別
static區域性變數只被初始化一次,下一次依據上一次結果值。函式static變數在函式中有效,第一次進入函式初始化(而不是進入相應的初始化語句)。以後進入函式將沿用上一次的值。
#include<iostream>
using namespace std;
int fun(void)
{
static int count = 10;// 事實上此賦值語句從來沒有執行過 函式中定義的static變數在第一次進入函式的時候初始化,而不執行這條語句
return count--;
}
int main(void)
{
cout<<"fun()="<<fun()<<endl; //輸出10
cout<<"fun()="<<fun()<<endl; //輸出9
cout<<"fun()="<<fun()<<endl; //輸出8
cout<<"fun()="<<fun()<<endl; //輸出7
cout<<"fun()="<<fun()<<endl; //輸出6
return 0;
}
對於普通區域性變數來說,程式如下
#include<iostream>
using namespace std;
int fun(void)
{
int count = 10;
return count--;
}
int main(void)
{
cout<<"fun()="<<fun()<<endl; //輸出10
cout<<"fun()="<<fun()<<endl; //輸出10
cout<<"fun()="<<fun()<<endl;
cout<<"fun()="<<fun()<<endl; //輸出10
cout<<"fun()="<<fun()<<endl; //輸出10
return 0;
}
對於普通區域性變數來說,每次進入函式初始化一次。
三、static區域性變數和static全域性變數的關係
1、初始化
全域性static變數的初始化在編譯的時候進行。在main函式被呼叫之前初始化並且只初始化一次 。
函式static變數(區域性static變數)在函式中有效,第一次進入函式初始化並且只初始化一次,以後進入函式將沿用上一次的值。
2、生存期生存期都是從main第一次執行,直到程式結束。
3、作用域
如果在{}中定義了static變數,則其作用域為{}內(針對的是區域性static變數),出了{},程式會指示相應的static變數未定義。如果將static變數定義為全域性的。則其擁有檔案作用域,只在宣告的檔案中有效,其他原始檔中不可見。
#include<iostream>
using namespace std;
int main(void)
{
for(int i = 0;i < 5;i++)
{
static int m = 7;
cout<<"m="<<m--;
}
cout<<m<<endl;//這裡會顯示錯誤
return 0;
}
四、全域性變數和static全域性變數的關係
全域性static變數的初始化在編譯的時候進行。在main函式被呼叫之前初始化並且只初始化一次 。
普通全域性變數前面加上static 就成了static全域性變數,他們的儲存方式都是一樣,存在靜態儲存區(全域性變數和靜態變數被分配到同一塊記憶體中,在以前的C語言中,全域性變數又分為初始化的和未初始化的,在C++裡面沒有這個區分了,他們共同佔用同一塊記憶體區)。區別在於作用範圍,普通全域性變數作用域是整個源程式,當一個程式有多個原始檔組成時候,普通全域性變數在每個原始檔中都是有效的,而靜態全域性變數則限制了作用域,只在定義該變數的原始檔中有效。在同一個源程式中的其他原始檔不能使用。由於靜態全域性變數的作用域限於一個原始檔內,只能為該原始檔內的函式公用,
因此可以避免在其它原始檔中引起錯誤。
註釋:static變數和全域性變數預設初始化為0。因為它們都儲存在靜態資料區。在靜態資料區,記憶體中所有的位元組預設值都是0x00。static變數不管是區域性還是全域性的,雖然只可以初始化一次,但是可以賦值,對於全域性的static變數只能賦值(在呼叫的相應函式中)。