作用:這個關鍵字的作用是為了確保這條指令不會因為編譯器的優化而省略,要求每次直接讀取變數原來的值。
volatile關鍵字是一種型別修飾符,它宣告的型別變數可能被某些編譯器的未知因素更改。例如作業系統、硬體或者其它的執行緒,當遇到這個關鍵字的時候,編譯器就不會再對**進行優化,從而可以提供對特殊地質的穩定訪問。
使用關鍵字的例子如下:
int volatile nvint;
當我們使用這個關鍵字生命的變數的時候,系統總是重新從它所在的記憶體中的讀取資料,即使剛剛讀取過該資料。而且將讀取的資料立即儲存。
例如:volatile int i=10;
int a=i;
//這之間的**並沒有明確告訴編譯器,對i進行過操作
int b=i;通常情況下,在優化的條件下,編譯器在發現兩次從i中讀資料的操作**中沒有對i進行任何操作的情況下,這時候會直接把上次讀取的資料放到b中。這時候如果變數i表示的是乙個暫存器變數將畫作和埠資料就很容易出錯,這時候新增了這個關鍵字就可以保證對特殊位址的穩定訪問。
int volatile nvint;
>>>>;當要求使用volatile 宣告的變數的值的時候,系統總是重新從它所在的記憶體讀取資料,即使它前面的指令剛剛從該處讀取過資料。而且讀取的資料立刻被儲存。
例如:volatile int i=10;
int a = i;
...//其他**,並未明確告訴
編譯器,對i進行過操作
int b = i;
>>>>volatile 指出 i是隨時可能發生變化的,每次使用它的時候必須從i的位址中讀取,因而
編譯器生成的彙編**會重新從i的位址讀取資料放在b中。而優化做法是,由於
編譯器發現兩次從i讀資料的**之間的**沒有對i進行過操作,它會自動把上次讀的資料放在b中。而不是重新從i裡面讀。這樣一來,如果i是乙個
暫存器變數或者表示乙個埠資料就容易出錯,所以說volatile可以保證對特殊位址的穩定訪問。
>>>>;注意,在vc6中,一般除錯模式沒有進行**優化,所以這個
關鍵字的作用看不出來。下面通過插入彙編**,測試有無volatile
關鍵字,對程式最終**的影響:
>>>>;首先,用classwizard建乙個win32 console工程,插入乙個voltest.cpp檔案,輸入下面的**:
>>
#i nclude
void main()
int b = i;
printf("i= %d",b);
}然後,在除錯版本模式執行程式,輸出結果如下:
i = 10
i = 32
然後,在release版本模式執行程式,輸出結果如下:
i = 10
i = 10
輸出的結果明顯表明,release模式下,
編譯器對**進行了優化,第二次沒有輸出正確的i值。下面,我們把 i的宣告加上volatile
關鍵字,看看有什麼變化:
#i nclude
void main()
int b = i;
printf("i= %d",b);
}分別在除錯版本和release版本執行程式,輸出都是:
i = 10
i = 32
這說明這個
關鍵字發揮了它的作用
這個例子我自己在vs2008上面自己試了一下,最後發現,不管怎麼樣,結果兩個最後都是10,這個讓我很鬱悶呀,雖然我基本上已經理解了這個關鍵字的作用,但是在實踐中並沒有體現出這個關鍵字的真正作用。
此外 ,還有很多情況會產生類似的效果,比如說多執行緒的程式中,多個程式都可以操作這個變數。
還有 ,當乙個程式和乙個外部裝置的某個狀態對應的時候,當外部裝置發生操作的時候,通過驅動程式和中斷事件改變了這個值,而此時程式並不知道。
總的來說,對於volatile型別的變數,系統每次用到他的時候,都是從記憶體中提取,而不會使用cache中的值。
使用地方:
一般情況下,這個關鍵字主要用在下面的情況
1、中斷服務程式中修改的供其他程式檢測的變數
2、多工環境下各任務間共享的標誌
3、儲存器對映的硬體暫存器,因為每次讀寫它都可能有不同的值。
C語言基礎知識 一 關鍵字
儲存類別說明符變數 auto register static extern thread local typedef 儲存型別限定符 const volatile restrict atomic 1 register 暫存器變數,c語言要求用register修飾的變數通常儲存在cpu的暫存器中,防止...
C 基礎知識複習 const關鍵字
沒事翻了下c primer,開卷有益吧,加深下印象,留個複習記錄如下 1 const 指標與指向 const物件的指標 const int p 指向const int 的指標 int const p 指向int的const指標 記憶方法 從右往左讀,讀作is a pointer to。2 const...
Java基礎知識 super關鍵字
1 繼承要注意的幾點 屬性和方法的不同。屬性不可重寫,屬性可以覆蓋 屬性沒有多型性,屬性值取決於引用型別 方法可以重寫,方法有多型性 方法的行為取決於物件而不取決於引用類 生成子類物件必須呼叫父類構造方法,子類構造方法必須和父類構造方法匹配。下面程式 中a.name與a.fn 分別為屬性和物件。繼承...