預編譯指令
1.
#if XXXXX
......
#endif
解釋:如果XXXXX為真,則順序執行,否則直接執行到#endif
2.
解釋:宏定義一個XXXX
3.
#if defined XXXXXX
.......
#endif
解釋:如果已經定義了XXXXXX,則順序執行,否則直接執行到#endif
4.
#ifndef XXXX
......
#endif
解釋:如果沒有定義XXXX,則順序執行,否則直接執行到#endif
修飾符
1.volatile:
例子:
volatile int i=;
int a=i;
//...
//其他代碼,并未明确告訴編譯器,對i進行過操作
int b=i;
volatile 指出 i是随時可能發生變化的,每次使用它的時候必須從i的位址中讀取,因而編譯器生成的彙編代碼會重新從i的位址讀取資料放在b中。而優化做法是,由于編譯器發現兩次從i讀資料的代碼之間的代碼沒有對i進行過操作,它會自動把上次讀的資料放在b中。而不是重新從i裡面讀。這樣一來,如果i是一個寄存器變量或者表示一個端口資料就容易出錯,是以說volatile可以保證對特殊位址的穩定通路。
【注】在vc6中,一般調試模式沒有進行代碼優化,是以這個關鍵字的作用看不出來。
典型例子:
for(int i=; i<; i++);
這個語句用來測試空循環的速度的
但是編譯器肯定要把它優化掉,根本就不執行
如果你寫成
for(volatile int i=; i<; i++);
它就會執行了
由于通路寄存器的速度要快過RAM,是以編譯器一般都會作減少存取外部RAM的優化。比如:
static int i = ;
int main(void)
{
//...
while()
{
if(i)
dosomething();
}
}
/*Interruptserviceroutine.*/
void ISR_2(void)
{
i=;
}
程式的本意是希望ISR_2中斷産生時,在main當中調用dosomething函數,但是,由于編譯器判斷在main函數裡面沒有修改過i,是以
可能隻執行一次對從i到某寄存器的讀操作,然後每次if判斷都隻使用這個寄存器裡面的“i副本”,導緻dosomething永遠也不會被調用。如果将變量加上volatile修飾,則編譯器保證對此變量的讀寫操作都不會被優化(肯定執行)。此例中i也應該如此說明。
更詳細解釋:https://baike.baidu.com/item/volatile/10606957?fr=aladdin