C語言中的volatile 讓我保持原樣

2022-05-14 12:57:16 字數 1343 閱讀 4890

volatile譯為:易變的。這不是和題目的讓我保持原樣矛盾了嗎?其實不然,在變數前加上該關鍵字修飾,確實是告訴編譯器,這個變數是乙個容易改變的變數,不要對它進行優化,每次都要到變數的位址中去讀取變數的資料,但正因為這樣,才是保持了變數的原樣,因為變數已經發生改變了,你卻操作的是沒有變化時的資料,這樣才讓變數失去了本應該保持的屬性。

eg:int a=1;

a=2;

a=3;

....

編譯器看到這樣的**,會覺得a的值只有a=3才有意義,所以把a儲存在乙個暫存器中,每次遇到a都在這個暫存器中去讀取資料,但是a是可能改變,比如中斷或者多執行緒的時候。這個有可能你測試它又是正確的,因為隨著你的優化等級提高,生成的彙編**會有很大不同,如果基礎不夠紮實,**的魯棒性就會減弱,要想不這樣,那麼需要程式設計師有足夠紮實的基本功。

1.我們先看volatile第乙個應用場景,在中斷服務函式中的使用。

/*   main.c */

int flag=0;

int main(void)

if(flag==2)

return 0;

}/* interrupt*/

void nvic_handler(void)

在這種情況下,編譯器可能會對其做優化,雖然中斷服務函式改變了flag的值,但是編譯器並沒有在變數記憶體中去讀取,而是在暫存器中讀取了flag之前的快取資料。在中斷函式中的互動變數,一定要加上volatile關鍵字修飾,這樣每次讀取flag的值都是在其記憶體位址中讀取的,確保是我們想要的資料。

2.多工環境下各任務間共享的標誌應該加volatile。原因其實和上面中斷一樣,要共享標誌,又不想讓編譯器優化了這一點,需要加上該修飾詞。

3.儲存器對映的硬體暫存器通常也要加voliate,因為每次對它的讀寫都可能有不同意義。

以stm32為例,暫存器中的資料也是時刻在變化的,我們也不想編譯器優化這一點,所以在庫函式中我們可以看到這樣的**。

這是暫存器的結構體,我們檢視字首__i 和__io到底是什麼?

可以看到,在暫存器的對映中,也需要volatile,因為暫存器的值也是可能隨時更改的。

通過上面,我們也應該明白那個問題。

乙個引數既可以是const還可以是volatile嗎?

可以的,例如唯讀的狀態暫存器。它是volatile因為它可能被意想不到地改變。它是const因為程式不應該試圖去修改它。軟體不能改變,並不意味著我硬體不能改變你的值,這就是微控制器中的應用。

C語言中的volatile

c中 volatile 作用 volatile單詞的意思是易變的,不確定的。在c中,被 volatile 修飾的變數,表示 1 該變數的值是可變的,可能隨時在程式外部被改變 2 使用該變數的時候,必須每次從該變數所在的位址所指的記憶體去讀,不能把它放在暫存器或者 cache 中重複訪問,可以保證對特...

C語言中的volatile

關鍵字volatile 有什麼含意 並給出三個不同的例子。乙個定義為volatile 的變數是說這變數可能會被意想不到地改變,這樣,編譯器就不會去假設這個變數的值了。精確地說就是,優化器在用到這個變數時必須每次都小心地重新讀取這個變數的值,而不是使用儲存在暫存器裡的備份。下面是 volatile 變...

C語言中的volatile

volatile是乙個型別 修飾符 type specifier 就像大家更熟悉的const一樣,它是被設計用來修飾被不同執行緒訪問和修改的變數。volatile 的作用是作為指令 關鍵字,確保本條指令不會因 編譯器的優化而省略,且要求每次 每次都小心地重新讀取這個變數的值,而不是使用儲存在暫存器裡...