天天看點

C/C++開發之基礎知識

預編譯指令

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