關於這方面的內容,我自己經驗不夠說得不夠清楚。但又想記錄下來,於是上網找了網友的提問。
**問題帖子:
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 修飾,那麼函式返回值 即位址 的內容不能被修改,...