面試點 解讀關鍵字volatile

2021-07-04 16:25:28 字數 1570 閱讀 3019

面試點:解讀關鍵字volatile

c語言面試題分析之一

一.volatile是什麼?

volatile關鍵字是一種型別修飾符,用它宣告的型別變數表示可以被某些編譯器未知的因素更改,比如:作業系統、硬體或者其它執行緒等。遇到這個關鍵字宣告的變數,編譯器對訪問該變數的**就不再進行優化,從而可以提供對特殊位址的穩定訪問。

二.編譯器優化是什麼意思?

int i = 5;

int a = i;

……int b = i;

編譯器發現兩次從i讀資料的**之間,並沒有對i進行過操作,它會自動把上次讀的資料放在b中,而不是重新從i裡面讀;

三.哪些情況,改變了記憶體中變數的值,編譯器不知道?

1.多執行緒應用中被幾個任務共享的變數;

2.乙個中斷服務子程式中會訪問到的非自動變數;

3.並行裝置的硬體暫存器(如:狀態暫存器);

四.何時需要使用volatile這個關鍵字?

嵌入式系統程式設計師經常同硬體、中斷、rtos等等打交道,所用會經常要求定義為volatile型別的變數。

五.使用volatile帶來什麼好處?

volatile int ncount;

當要求使用volatile 宣告的變數的值的時候,系統總是重新從它所在的記憶體讀取資料,即使它前面的指令剛剛從該處讀取過資料。而且讀取的資料立刻被儲存。

六.3個經典的volatile問題

1). 乙個引數既可以是const還可以是volatile嗎?解釋為什麼。

2). 乙個指標可以是volatile 嗎?解釋為什麼。

3). 下面的函式有什麼錯誤:

int square(volatile int *ptr)

下面是答案:

1). 可以是。例如對於唯讀的狀態暫存器而言,如果它僅僅是volatile型別,那麼它還是可能被意想不到的改變。但它還是const的時候,程式就不應該試圖去修改它

2). 可以是的。

儘管這種情況並不常見,但它還是可以。乙個例子就是:

當乙個中斷服務子程式企圖去修改乙個指向乙個buffer指標的時候。

3). 這段**可能有點惡作劇的味道。但它很好說明volatile型別引數的含義和作用。

這段**的目的是用來返指標*ptr所指向的值的平方,

但是,由於*ptr指向乙個volatile型引數,編譯器將產生類似下面的**:

int square(volatile int *ptr)

由於*ptr的值可能被意想不到地該變,因此a和b可能是不同的。結果,這段**可能返不

是你所期望的平方值!正確的**如下:

long square(volatile int *ptr)

七.總結

1.使用volatile關鍵字修飾的變數,可以避免編譯器優化;

2.使用volatile關鍵字修飾的變數,每次都是重新讀取記憶體中的值,而不是使用儲存在暫存器裡的值了;

3.編譯器優化的做法是:

int i = 5;

int a = i;

……int b = i;

編譯器發現兩次從i讀資料的**之間,並沒有對i進行過操作,它會自動把上次讀的資料放在b中,而不是重新從i裡面讀。

解讀synchronized關鍵字

size large 最近在寫多執行緒程式,網上收集總結了synchronized的用法,結果如下 size 1 synchronized關鍵字的作用域有二種 1 是某個物件例項內,synchronized amethod 可以防止多個執行緒同時訪問這個物件的synchronized方法 如果乙個物...

c 關鍵字盲點解析

volatile 指出變數易變,這裡的易變是指不為編譯器知道的變化,通常來自作業系統,硬體或其他執行緒。該引數不與const衝突,const只是在編譯層面上保證變數的常量性,即不可賦值性,是一種在編譯時期的保證。故,const 和volatile可共同修飾某一變數,volatile也可修飾指標,vo...

volatile關鍵字深入解讀

volatile關鍵字可以保證 1.實時性 2.有序性 禁止指令重排序 指令重排序指程式執行期間的優化,發生在相同 指令以不同順序執行時在單執行緒內的結果一致時的優化手段,但是這種優化會在併發環境下出現問題。操作變數值時,會將變數值從主存中讀取,載入至快取中 l1 cache或l2 cache等 指...