1.static全局變量與普通的全局變量有什麼差別?static局部變量與普通局部變量有什麼差別?static函數與普通函數有什麼差別?關鍵字static的作用是什麼?在什麼情況下用(我筆試很多次,基本上都有這個題)
再說這塊之前首先說一下C的存儲:
一般認為在c中分為這幾個存儲區:
- 棧 --有編譯器自動配置設定釋放
- 堆 --一般由程式員配置設定釋放,若程式員不釋放,程式結束時可能由OS回收
- 全局區(靜态區) --全局變量和靜态變量的存儲是放在一塊的,初始化的全局變量和靜态變量在一塊區域,未初始化的全局變量和未初始化的靜态變量在相鄰的另一塊區域。程式結束釋放。
-
另外還有一個專門放常量的地方。程式結束釋放
1)static全局變量與普通全局變量有什麼差別?
先看兩個例子:第一個是:普通的全局變量
怎樣了解static/const/volatile 怎樣了解static/const/volatile 怎樣了解static/const/volatile 第二個是靜态全局變量:
和上面的例子唯一修改的就是這個部分:
怎樣了解static/const/volatile 總結:靜态全局變量和普通全局變量的不同就是:非靜态全局變量可以作用于多個源檔案(整個工程)而靜态全局變量隻能作用一定義它的一個源檔案,同一工程的其他源檔案不能使用。他們的相同點是:全局變量和靜态全局變量都是靜态存儲方式。
我們可以這樣了解:把全局變量改成靜态全局變量是改變了它的作用域。
2)靜态局部變量與普通局部變量有什麼差別?
靜态局部變量隻能初始化一次,下一依據上一次的結果;
靜态局部變量不能被同一個源檔案的其他函數調用。怎樣了解static/const/volatile 怎樣了解static/const/volatile 當static用來修飾局部變量的時候,它就改變了局部變量的存儲位置,從原來的棧中存放改為靜态存儲區。但是局部靜态變量在離開作用域之後,并沒有被銷毀,而是仍然駐留在記憶體當中,直到程式結束,隻不過我們不能再對他進行通路。
3)靜态函數與普通函數的差別
在函數的傳回類型前加上關鍵字static,函數就被定義成為靜态函數。
函數的定義和聲明預設情況下是extern的,但靜态函數隻是在聲明他的檔案當中可見,不能被其他檔案所用。這個類似靜态全局變量和普通全局變量。
定義靜态函數的好處:22
<1> 其他檔案中可以定義相同名字的函數,不會發生沖突
<2> 靜态函數不能被其他檔案所用。 存儲說明符auto,register,extern,static,對應兩種存儲期:自動存儲期和靜态存儲期。 auto和register對應自動存儲期。具有自動存儲期的變量在進入聲明該變量的程式塊時被建立,它在該程式塊活動時存在,退出該程式塊時撤銷。
關鍵字extern和static用來說明具有靜态存儲期的變量和函數。用static聲明的局部變量具有靜态存儲持續期(static storage duration),或靜态範圍(static extent)。雖然他的值在函數調用之間保持有效,但是其名字的可視性仍限制在其局部域内。靜态局部對象在程式執行到該對象的聲明處時被首次初始化。
對上面的三個方面總結一下:
(1)在一個工程裡,靜态全局變量和普通全局變量都存儲在靜态存儲區,但是靜态全局變量的作用域知隻是定義靜态全局變量的源檔案,而普通全局變量
作用域是整個工程。
(2)靜态局部變量和普通局部變量:靜态局部變量存儲在靜态存儲區。而普通局部變量存儲在棧。靜态局部變量隻能初始化一次,并且在函數調用過程中維持其值不變,其作用域是定義靜态局部變量的函數内。
(3)靜态函數和普通函數,靜态函數的作用域隻是在定義靜态函數的源檔案,不能被其他源檔案調用,并且其他源檔案可以使用和靜态函數相同的函數名。
在我的做DSP開發的幾年了,我自己寫代碼用的靜态變量用的比較少,除非反而經常會有靜态函數,比如關于網口發射接受的函數就是靜态函數,并且在一個源檔案裡面,作用就是限制了調用函數的範圍,以後發射或者接受部分的都在一個源檔案裡面完成。
2.關鍵字volatile的作用是什麼?在什麼情況下用?(筆試很多次,基本上都有這個題,務必了解甚至背誦,不知道這個問題,說明你嵌入式沒有入行。)
1)定義:
volatile是一個類型修飾符(type specifier),一個定義為volatile的變量是說這變量可能會被意想不到的改變,這樣編譯器就不會假設這個變量的值了,優化器用到這個變量時必須每次都小心地重新讀取這個值,而不是使用儲存到寄存器裡的備份。
第一:并行裝置的寄存器(如裝置寄存器)
第二:一個中斷子程式會通路到的非自動變量(nan-automatic variables)
第三:多線程任務被幾個任務共享的時候。
在我工作中:公司是做衛地面檢測,DSP主要完成捕獲,跟蹤的算法,
捕獲的通道号以及捕獲的結果都會用動态變量。跟蹤部分: FPGA送來的相關值dsp都會定義程動态變量,以及根據相關知識計算出來的鑒相,鑒頻誤差結果還有最後算出來的頻率控制字都是需要定義為volatile變量,在實際工作中那些比較重要,又經改變的變量都推薦定義動态變量。另外就是指針指向的記憶體空間經常改變,這個指針也會定義成volatile指針。
舉個例子,一般在筆試的時候容易考到:
怎樣了解static/const/volatile 怎樣了解static/const/volatile 3.const(之前提到過,這次再完善一下)
const是什麼?相對準确的答案是:const意味着隻讀。
const int a; int const a ; const int *a ; int *const a ; int const *const a;
const int a; 和 int const a ;兩個作用一樣,a是常整形數
怎樣了解static/const/volatile 怎樣了解static/const/volatile const int *a 指針變量存儲的位址可以變,但是指針指向的值不變;怎樣了解static/const/volatile 怎樣了解static/const/volatile int *const a 指針變量存儲的位址不能變,指針指向的值可以變。怎樣了解static/const/volatile 怎樣了解static/const/volatile int const *const a; 指針變量存儲的位址,和指針指向值都不能變怎樣了解static/const/volatile 怎樣了解static/const/volatile 怎樣了解static/const/volatile 總結一下為什麼要用const:
第一:const聲明了一個參數為常量,就是告訴人們就是直接告訴人們這個參數的目的。
第二:通過優化器的一些附加資訊,代碼更加緊湊。
第三:保護不希望更改的參數,防止被無意的代碼修改,可以減少bug。