1. 程式人生 > >普通區域性變數、普通全域性變數、static區域性變數、static全域性變數

普通區域性變數、普通全域性變數、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變數只能賦值(在呼叫的相應函式中)。