筆記 關於const和volatile

2021-10-03 06:25:14 字數 1862 閱讀 1771

關於這方面的內容,我自己經驗不夠說得不夠清楚。但又想記錄下來,於是上網找了網友的提問。

**問題帖子:

1.volatile

volatile標識乙個變數意味著這個變數可能被非本程式的其他過程改變,例如某個訪問這一變數的某中斷程式。為變數加上這一標識可以禁止編譯器的優化,使程式正確地按設計者的意圖執行。例如下面的程式,我們將intr_func註冊為中斷函式,某個中斷發生時觸發這一函式:

unsigned

char flag =1;

intmain

(int argc,

char

**ar**)

return0;

}void

intr_func

(void

)

當不加volatile時,編譯器會直接將while條件中的flag換成1,因此即使中斷發生也無法結束迴圈;如果給flag加上volatile標識,編譯器就不會做前述的優化,程式得以按設計的意圖工作。

2.const是唯讀變數,不是常量

唯讀表示編譯器不允許**修改變數。但並不表示這個變數在其它地方不能夠被修改(不能被修改豈不就成了常量?)。比如:

voidf(

const

char

*str)

在上面的程式中,str所指向的記憶體區域就是唯讀的,但這個唯讀性只在函式f內部,出了f,這塊記憶體完全有可能是能夠被修改的。

voidg(

void

)

而在另乙個函式,是可以將不同的實參傳進 f 函式中去的。

3. volatile的另乙個例子(與const聯用)

另外乙個例子在嵌入式系統中比較常見。很多嵌入式系統允許我們訪問外部暫存器,該暫存器的位址可能是0x0018,該暫存器的最低位可能表示裝置狀態,1為忙碌,0為空閒。

#define get_reg_value(reg)              (*reg)       

/* get register value */

const

unsigned

char

*status_reg =

0x0018

;/* status register */

const

unsigned

char status_busy =

0x01

;/* busy bit */

while

(get_reg_value

(status_reg)

& status_busy)

;/* wait until free */

// do something to operate the device

這段**很可能會死迴圈。因為編譯器**民意的將位址0x0018處的值快取起來,然後每次while的時候都從快取中讀取。雖然status_reg的值是const unsigned char *,但這僅僅表示status_reg暫存器是個唯讀暫存器,我們不能夠在**中去寫這個暫存器,但並不表示這個暫存器是不能夠改變的。硬體完成了它的任務之後,就會把狀態設定成空閒,因此該暫存器的最後一位在我們迴圈的時候很可能已經發生了變化。因此在這樣的地方,我們要禁止編譯器自作聰明的優化,方法如下:

const

volatile

unsigned

char

*status_reg =

0x0018

;/* status register */

關於const的筆記

今天讓指標常量,常量指標的說法搞糊塗了,原理明白,但是叫法上的區分糊塗呵呵!const是c特別是c 中經常遇到的東西,能靈活的運用可以體現你的cc 的水平。1.常量和預編譯 我們都知道在c中用到常量往往是通過預編譯來實現,但是這樣最大的缺點是不能夠進行型別檢查,使用const修飾變數就可以客服這樣的...

關於const的筆記

今天讓指標常量,常量指標的說法搞糊塗了,原理明白,但是叫法上的區分糊塗呵呵!const是c特別是c 中經常遇到的東西,能靈活的運用可以體現你的cc 的水平。常量和預編譯 我們都知道在c中用到常量往往是通過預編譯來實現,但是這樣最大的缺點是不能夠進行型別檢查,使用const修飾變數就可以客服這樣的缺點...

關於const和函式

關於 const 和函式void fun const const void fun 和void const fun 的區別?答 const void fun 和void const fun 兩個相同。如果採用 按址傳遞方式 的函式返回值加 const 修飾,那麼函式返回值 即位址 的內容不能被修改,...