當前位置:首頁 » 編程軟體 » 靜態局部變數對編譯器影響

靜態局部變數對編譯器影響

發布時間: 2022-04-27 14:59:30

㈠ 靜態變數與非靜態變數的區別

1、存儲位置不同

靜態變數:存儲在全局數據區(靜態數據區)。

非靜態變數叫動態變數:存儲在內存出棧數據區。

2、生命期不同

動態變數:根據你定義的位置確定,比如你在一個函數中定義的,那麼超出該函數范圍變數將失效。

靜態變數:程序結束時才釋放。

3、作用域不同

動態變數:同樣的要根據你定義的位置才能確定,和第二點的一樣。

靜態變數:當前文件中有效。

(1)靜態局部變數對編譯器影響擴展閱讀;

靜態變數的作用;

1、對於靜態全局變數,源文件靜態聲明的文件級變數和函數的作用域僅限於文件(僅在文件中可見),即內部連接,因此可以用來限制變數的作用域。

2、對於靜態局部變數,雖然函數內靜態聲明的變數范圍與自動局部變數的范圍相同(即范圍僅在函數內),但存儲空間是通過靜態分配而不是默認的自動分配獲得的。

所以存儲空間在不同的區域是不同的(一般來說,靜態分配時在編譯時在程序數據段中劃分存儲空間,一次性分配在整個過程中是有效的。而在自動分配時,存儲空間是在調用堆棧上分配的,只分配和釋放在調用期間),兩個調用之間的變數值總是一致的。必須注意,靜態局部變數只能初始化一次,這是由編譯器保證的。

3、對於靜態成員變數,在C++中,類定義中靜態聲明的成員變數屬於類變數,即它們在所有類實例中共享,相反是過程變數。

參考資料來源;網路——靜態變數

網路——動態變數

㈡ 全局變數,靜態全局變數,靜態局部變數和局部變數的區別1

全局變數、靜態全局變數、靜態局部變數和局部變數的區別
變數可以分為:全局變數、靜態全局變數、靜態局部變數和局部變數。
按存儲區域分,全局變數、靜態全局變數和靜態局部變數都存放在內存的靜態存儲區域,局部變數存放在內存的棧區。
按作用域分,全局變數在整個工程文件內都有效;靜態全局變數只在定義它的文件內有效;靜態局部變數只在定義它的函數內有效,只是程序僅分配一次內存,函數返回後,該變數不會消失;局部變數在定義它的函數內有效,但是函數返回後失效。
全局變數(外部變數)的說明之前再冠以static 就構成了靜態的全局變數。全局變數本身就是靜態存儲方式, 靜態全局變數當然也是靜態存儲方式。 這兩者在存儲方式上並無不同。這兩者的區別雖在於非靜態全局變數的作用域是整個源程序, 當一個源程序由多個源文件組成時,非靜態的全局變數在各個源文件中都是有效的。 而靜態全局變數則限制了其作用域, 即只在定義該變數的源文件內有效, 在同一源程序的其它源文件中不能使用它。由於靜態全局變數的作用域局限於一個源文件內,只能為該源文件內的函數公用, 因此可以避免在其它源文件中引起錯誤。
從以上分析可以看出, 把局部變數改變為靜態變數後是改變了它的存儲方式即改變了它的生存期。把全局變數改變為靜態變數後是改變了它的作用域, 限制了它的使用范圍。
static函數與普通函數作用域不同。僅在本文件。只在當前源文件中使用的函數應該說明為內部函數(static),內部函數應該在當前源文件中說明和定義。對於可在當前源文件以外使用的函數,應該在一個頭文件中說明,要使用這些函數的源文件要包含這個頭文件
static全局變數與普通的全局變數有什麼區別:static全局變數只初使化一次,防止在其他文件單元中被引用;
static局部變數和普通局部變數有什麼區別:static局部變數只被初始化一次,下一次依據上一次結果值;
static函數與普通函數有什麼區別:static函數在內存中只有一份,普通函數在每個被調用中維持一份拷貝
全局變數和靜態變數如果沒有手工初始化,則由編譯器初始化為0。局部變數的值不可知。

㈢ 假設一個順序執行的C/C++源文件中,一個靜態變數從某一位置起不再被使用了。那麼編譯器會不會,使該變數占

1.靜態局部變數在函數內定義,但不象自動變數那樣,當調用時就存在,退出函數時就消失。靜態局部變數始終存在著,也就是說它的生存期為整個源程序。
2. 根據靜態局部變數的特點, 可以看出它是一種生存期為整個源程序的量。雖然離開定義它的函數後不能使用,但如再次調用定義它的函數時,它又可繼續使用, 而且保存了前次被調用後留下的值。 因此,當多次調用一個函數且要求在調用之間保留某些變數的值時,可考慮採用靜態局部變數。

㈣ 局部靜態變數的引用問題。。。先謝謝啦!

保留字肯定就是關鍵字撒,
(1)auto
這個這個關鍵字用於聲明變數的生存期為自動,即將不在任何類、結構、枚舉、聯合和函數中定義的變數視為全局變數,而在函數中定義的變數視為局部變數。這個關鍵字不怎麼多寫,因為所有的變數默認就是auto的。

(2)register
這個關鍵字命令編譯器盡可能的將變數存在CPU內部寄存器中而不是通過內存定址訪問以提高效率。

(3)static
常見的兩種用途:
1>統計函數被調用的次數;
2>減少局部數組建立和賦值的開銷.變數的建立和賦值是需要一定的處理器開銷的,特別是數組等含有較多元素的存儲類型。在一些含有較多的變數並且被經常調用的函數中,可以將一些數組聲明為static類型,以減少建立或者初始化這些變數的開銷.

詳細說明:
1>、變數會被放在程序的全局存儲區中,這樣可以在下一次調用的時候還可以保持原來的賦值。這一點是它與堆棧變數和堆變數的區別。
2>、變數用static告知編譯器,自己僅僅在變數的作用范圍內可見。這一點是它與全局變數的區別。
3>當static用來修飾全局變數時,它就改變了全局變數的作用域,使其不能被別的程序extern,限制在了當前文件里,但是沒有改變其存放位置,還是在全局靜態儲存區。

使用注意:
1>若全局變數僅在單個C文件中訪問,則可以將這個變數修改為靜態全局變數,以降低模塊間的耦合度;
2>若全局變數僅由單個函數訪問,則可以將這個變數改為該函數的靜態局部變數,以降低模塊間的耦合度;
3>設計和使用訪問動態全局變數、靜態全局變數、靜態局部變數的函數時,需要考慮重入問題(只要輸入數據相同就應產生相同的輸出)

(4)const
被const修飾的東西都受到強制保護,可以預防意外的變動,能提高程序的健壯性。它可以修飾函數的參數、返回值,甚至函數的定義體。
作用:
1>修飾輸入參數
a.對於非內部數據類型的輸入參數,應該將「值傳遞」的方式改為「const引用傳遞」,目的是提高效率。例如將void Func(A a) 改為void Func(const A &a)。
b.對於內部數據類型的輸入參數,不要將「值傳遞」的方式改為「const引用傳遞」。否則既達不到提高效率的目的,又降低了函數的可理解性。例如void Func(int x) 不應該改為void Func(const int &x)。
2>用const修飾函數的返回值
a.如果給以「指針傳遞」方式的函數返回值加const修飾,那麼函數返回值(即指針)的內容不能被修改,該返回值只能被賦給加const修飾的同類型指針。
如對於: const char * GetString(void);
如下語句將出現編譯錯誤:
char *str = GetString();//cannot convert from 'const char *' to 'char *';
正確的用法是:
const char *str = GetString();
b.如果函數返回值採用「值傳遞方式」,由於函數會把返回值復制到外部臨時的存儲單元中,加const修飾沒有任何價值。 如不要把函數int GetInt(void) 寫成const int GetInt(void)。
3>const成員函數的聲明中,const關鍵字只能放在函數聲明的尾部,表示該類成員不修改對象.

說明:
const type m; //修飾m為不可改變
示例:
typedef char * pStr; //新的類型pStr;
char string[4] = "abc";
const char *p1 = string;
p1++; //正確,上邊修飾的是*p1,p1可變
const pStr p2 = string;
p2++; //錯誤,上邊修飾的是p2,p2不可變,*p2可變
同理,const修飾指針時用此原則判斷就不會混淆了。

const int *value; //*value不可變,value可變
int* const value; //value不可變,*value可變
const (int *) value; //(int *)是一種type,value不可變,*value可變
//邏輯上這樣理解,編譯不能通過,需要tydef int* NewType;
const int* const value;//*value,value都不可變

(5)volatile
表明某個變數的值可能在外部被改變,優化器在用到這個變數時必須每次都小心地重新讀取這個變數的值,而不是使用保存在寄存器里的備份。它可以適用於基礎類型如:int,char,long......也適用於C的結構和C++的類。當對結構或者類對象使用volatile修飾的時候,結構或者類的所有成員都會被視為volatile.
該關鍵字在多線程環境下經常使用,因為在編寫多線程的程序時,同一個變數可能被多個線程修改,而程序通過該變數同步各個線程。
簡單示例:
DWORD __stdcall threadFunc(LPVOID signal)
{
int* intSignal=reinterpret_cast(signal);
*intSignal=2;
while(*intSignal!=1)
sleep(1000);
return 0;
}
該線程啟動時將intSignal 置為2,然後循環等待直到intSignal 為1 時退出。顯然intSignal的值必須在外部被改變,否則該線程不會退出。但是實際運行的時候該線程卻不會退出,即使在外部將它的值改為1,看一下對應的偽匯編代碼就明白了:
mov ax,signal
label:
if(ax!=1)
goto label
對於C編譯器來說,它並不知道這個值會被其他線程修改。自然就把它cache在寄存器裡面。C 編譯器是沒有線程概念的,這時候就需要用到volatile。volatile 的本意是指:這個值可能會在當前線程外部被改變。也就是說,我們要在threadFunc中的intSignal前面加上volatile關鍵字,這時候,編譯器知道該變數的值會在外部改變,因此每次訪問該變數時會重新讀取,所作的循環變為如下面偽碼所示:
label:
mov ax,signal
if(ax!=1)
goto label

注意:一個參數既可以是const同時是volatile,是volatile因為它可能被意想不到地改變。它是const因為程序不應該試圖去修改它。

(6)extern
extern 意為「外來的」···它的作用在於告訴編譯器:有這個變數,它可能不存在當前的文件中,但它肯定要存在於工程中的某一個源文件中或者一個Dll的輸出中。

參考

另外:c語言中的關鍵字
auto :聲明自動變數 一般不使用
double :聲明雙精度變數或函數
int: 聲明整型變數或函數
struct:聲明結構體變數或函數
break:跳出當前循環
else :條件語句否定分支(與 if 連用)
long :聲明長整型變數或函數
switch :用於開關語句
case:開關語句分支
enum :聲明枚舉類型
register:聲明積存器變數
typedef:用以給數據類型取別名(當然還有其他作用)
char :聲明字元型變數或函數
extern:聲明變數是在其他文件正聲明(也可以看做是引用變數)
return :子程序返回語句(可以帶參數,也看不帶參數)
union:聲明聯合數據類型
const :聲明只讀變數
float:聲明浮點型變數或函數
short :聲明短整型變數或函數
unsigned:聲明無符號類型變數或函數
continue:結束當前循環,開始下一輪循環
for:一種循環語句(可意會不可言傳)
signed:生命有符號類型變數或函數
void :聲明函數無返回值或無參數,聲明無類型指針(基本上就這三個作用)
default:開關語句中的「其他」分支
goto:無條件跳轉語句
sizeof:計算數據類型長度
volatile:說明變數在程序執行中可被隱含地改變
do :循環語句的循環體
while :循環語句的循環條件
static :聲明靜態變數
if:條件語句

㈤ 靜態局部變數和普通全局變數以及靜態全局變數的區別

靜態局部變數和普通全局變數以及靜態全集變數在編譯時,編譯器會自動給他們分配地址。而且是從MCU上電運行開始,一直駐留,不會被回收的。

而真正的區別在於他們的作用域。
靜態局部變數的作用域是在於定義它的那個函數內。由於其在編譯時編譯器就給他們分配了地址,並且做了初始化,所以它只能被初始化一次,而且看起來的順序是程序每執行到這個函數時,都會執行那條定義語句,其實 並!沒!有! 因為它已經被分配地址了,而且始終駐留在RAM中。而剝離這點,其他特性都與普通的局部變數相同。

普通全局變數,在本文件內可以被無限制地使用。而且其他的源文件中,也可以通過extern關鍵字引用後使用。

而靜態全局變數則是在普通全局變數的基礎上,取消了extern關鍵字引用,即無論怎麼樣,只能給本文件的程序使用,其他文件不能使用。(保護代碼模塊化,封閉外部介面)。

㈥ C語言——局部靜態變數的問題

其實是這樣的。靜態變數在內存中存儲的位置,與全局變數是同一個區域。
所以,在編譯期間,它的存儲和大小就已經確定了,也就是已經分配了空間了。
而在c語言中,「分配內存」往往看做是變數被定義的一個標志。
所以,你在運行程序的時候,由於靜態變數已經分配過內存了,不會再次進行分配了,它的定義語句就不會再次被執行了。

㈦ C++成員函數中的靜態局部變數能不能提高程序的執行效率

我想是可以提高效率的,靜態局部變數只在第一次調用定義該局部靜態變數的函數中初始化,在這之後即使重復調用該函數,該靜態變數不再初始化,這可以節省下重新分配內存並初始化的開銷。

㈧ <初級問題>static靜態局部變數問題

加 static 則將原來的變數改為全局變數,在退出count函數時,
ctr並沒有被銷毀,所以++ctr時ctr值一直在增加,從而輸出1-10

不加 static ,ctr為局部變數,在退出count函數時,ctr被銷毀,所以每次的值都是1

實際上加 static 標識的局部變數,編譯器會給被 static 標識的局部變數,分配獨立的空間。從而實現局部變數全局化。

㈨ 靜態變數和局部變數和全局變數的區別

1.從作用域看:
C++變數根據定義的位置的不同的生命周期,具有不同的作用域,作用域可分為6種:
全局作用域,局部作用域,語句作用域,類作用域,命名空間作用域和文件作用域。
1>全局變數具有全局作用域。全局變數只需在一個源文件中定義,就可以作用於所有的源文件。當然,其他不包含全局變數定義的源文件需要用extern關鍵字再次聲明這個全局變數。
2>靜態局部變數具有局部作用域,它只被初始化一次,自從第一次被初始化直到程序運行結束都一直存在,它和全局變數的區別在於全局變數對所有的函數都是可見的,而靜態局部變數只對定義自己的函數體始終可見。
3>局部變數也只有局部作用域,它是自動對象(auto),它在程序運行期間不是一直存在,而是只在函數執行期間存在,函數的一次調用執行結束後,變數被撤銷,其所佔用的內存也被收回。
4>靜態全局變數也具有全局作用域,它與全局變數的區別在於如果程序包含多個文件的話,它作用於定義它的文件里,不能作用到其它文件里,即被static關鍵字修飾過的變數具有文件作用域。這樣即使兩個不同的源文件都定義了相同名字的靜態全局變數,它們也是不同的變數。
2.從分配內存空間看:
1>全局變數,靜態局部變數,靜態全局變數都在靜態存儲區分配空間,而局部變數在棧里分配空間
2>全局變數本身就是靜態存儲方式,靜態全局變數當然也是靜態存儲方式。這兩者在存儲方式上並無不同。這兩者的區別雖在於非靜態全局變數的作用域是整個源程序,當一個源程序由多個源文件組成時,非靜態的全局變數在各個源文件中都是有效的。而靜態全局變數則限制了其作用域,即只在定義該變數的源文件內有效,在同一源程序的其它源文件中不能使用它。由於靜態全局變數的作用域局限於一個源文件內,只能為該源文件內的函數公用,因此可以避免在其它源文件中引起錯誤。
1)全局變數、靜態全局變數以及靜態局部變數都會被放在程序的靜態數據存儲區(全局可見)中,這樣可以在下一次調用的時候還可以保持原來的賦值。這一點是它們與堆變數、堆變數的區別。
2)靜態變數(包括靜態局部變數和靜態全局變數)用static告知編譯器,自己僅僅在變數的作用范圍內可見。這一點是它與全局變數的區別。
從以上分析可以看出,把局部變數改變為靜態變數後是改變了它的存儲方式即改變了它的生存期。把全局變數改變為靜態變數後是改變了它的作用域,限制了它的使用范圍。因此static這個說明符在不同的地方所起的作用是不同的。應予以注意。
Tips:
A.若全局變數僅在單個C文件中訪問,則可以將這個變數修改為靜態全局變數,以降低模塊間的耦合度;
B.若全局變數僅由單個函數訪問,則可以將這個變數改為該函數的靜態局部變數,以降低模塊間的耦合度;
C.設計和使用訪問動態全局變數、靜態全局變數、靜態局部變數的函數時,需要考慮重入問題,因為他們都放在靜態數據存儲區,全局可見;
D.如果我們需要一個可重入的函數,那麼,我們一定要避免函數中使用static變數(這樣的函數被稱為:帶「內部存儲器」功能的的函數)
E.函數中必須要使用static變數情況:比如當某函數的返回值為指針類型時,則必須是static的局部變數的地址作為返回值,若為auto類型,則返回為錯指針。

熱點內容
我的世界礦石島伺服器宣傳片 發布:2024-05-05 02:17:19 瀏覽:612
如何區分安卓原裝充電器 發布:2024-05-05 01:41:23 瀏覽:72
怎麼從蘋果轉移到安卓 發布:2024-05-05 01:41:20 瀏覽:721
支付寶付款碼怎麼設置密碼 發布:2024-05-05 01:27:36 瀏覽:878
qtp錄制的腳本 發布:2024-05-05 01:14:04 瀏覽:367
如何安裝卡羅拉安卓系統 發布:2024-05-05 01:09:00 瀏覽:985
sql創建表查詢表 發布:2024-05-05 01:00:12 瀏覽:799
食色抖音上傳 發布:2024-05-05 00:55:56 瀏覽:658
java圖片下載 發布:2024-05-05 00:50:45 瀏覽:598
唱吧如何上傳伴奏 發布:2024-05-05 00:49:04 瀏覽:445