C语言学习及应用笔记之四:C语言volatile关键字及其使用
在C語言中,還有一個(gè)并不經(jīng)常使用但卻非常有用的關(guān)鍵字volatile。那么使用volatile關(guān)鍵字究竟能干什么呢?接下來我將就此問題進(jìn)行討論。
一個(gè)使用volatile關(guān)鍵字定義變量,其實(shí)就是告訴編譯系統(tǒng)這變量可能會(huì)被意想不到地改變。那么編譯時(shí),編譯器就不會(huì)自作主張的去假設(shè)這個(gè)變量的值,而進(jìn)行代碼的優(yōu)化了。確切的說就是,編譯器在編譯代碼時(shí),優(yōu)化器每次遇到這個(gè)變量,都會(huì)到內(nèi)存中重新讀取,而不會(huì)使用保存在寄存器里的備份來對(duì)代碼進(jìn)行優(yōu)化。
我們已經(jīng)了解了volatile關(guān)鍵字的基本作用。那么,在什么情況下使用volatile關(guān)鍵字呢?一般說來,在如下的幾種情況通常會(huì)使用volatile關(guān)鍵字:
-
在中斷服務(wù)程序中修改的,供其它程序檢測(cè)的變量,通常需要定義為volatile;
-
在多任務(wù)環(huán)境下,各任務(wù)間共享的標(biāo)志,通常也需要定義為volatile;
-
存儲(chǔ)器映射的硬件寄存器通常也需要定義為volatile,因?yàn)槊看螌?duì)它的讀寫都可能有不同意義;
(1)使用中斷改變對(duì)象值的情況
我們?cè)谥袛喾?wù)程序中操作了某個(gè)對(duì)象,比如誰改變了一個(gè)變量的值。而在其它程序中我們希望通過這個(gè)變量值得改變?nèi)ミM(jìn)行一些操作。在這個(gè)時(shí)候,我們使用或者不使用volatile關(guān)鍵字,可能得到截然不同的結(jié)果。
如果我們將變量定義為:static int var=0;?,然后再中斷服務(wù)成勛中將其修改為:var=1,但是在另一函數(shù)中使用它但不會(huì)修改它,那么編譯器會(huì)認(rèn)為它沒有變化,從而直接使用寄存器中的副本。
如果我們將變量定義為:volatile int var=0;,那么結(jié)果就完全不同了,每次在函數(shù)中使用var變量時(shí),都會(huì)重新讀取,而不會(huì)使用寄存器中的副本。
(2)多任務(wù)共享標(biāo)志的情況
多任務(wù)共享時(shí),其實(shí)也是一樣的,在一個(gè)任務(wù)中修改了一個(gè)對(duì)象后,在另一個(gè)對(duì)象中應(yīng)用它,但編譯器并沒發(fā)現(xiàn)在該任務(wù)中對(duì)它有修改。由于訪問寄存器的速度要快過RAM,所以編譯器一般都會(huì)作減少存取外部RAM的優(yōu)化。從而并不能響應(yīng)在另一任務(wù)下的變化。
在這種情況下,一般我們都需要使用volatile關(guān)鍵字來定義任務(wù)間共享的標(biāo)識(shí)。
(3)硬件寄存器內(nèi)存映射的情況
內(nèi)存映射的情況是非常多的,比如我們將外設(shè)的寄存器映射到內(nèi)存的某一段區(qū)域;再比如我們同過DMA方式將數(shù)據(jù)直接寫到內(nèi)存中的某一段區(qū)域。
由于我們外部的數(shù)據(jù)都是直接進(jìn)入了內(nèi)存區(qū)域,而程序知識(shí)引用它的值。編譯器優(yōu)化時(shí)可能就直接采用寄存器中的副本了。佷顯然這不是我們需要的結(jié)果,這時(shí)將這段內(nèi)存對(duì)應(yīng)的變量聲明為volatile,則可以保證我們的需求。
綜上所述,我們說明了volatile關(guān)鍵字的常規(guī)用法。當(dāng)然,我們也可以發(fā)現(xiàn)volatile關(guān)鍵字是會(huì)降低編譯器優(yōu)化力度的,但它卻可以保證程序的正確性,所以在適合的地方使用volatile關(guān)鍵字是必要的。不過能不能用的好,還要看編程者的基本功。
歡迎關(guān)注:
總結(jié)
以上是生活随笔為你收集整理的C语言学习及应用笔记之四:C语言volatile关键字及其使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PID控制器开发笔记之七:微分先行PID
- 下一篇: android语言列表+波斯,Andro