C語言學習筆記(五) 預處理符號

關於預處理的“常識”

  • 預處理並不是編譯,也不是“預編譯”。

  • 預處理並不是每個語言都有的。

  • C/C++預處理僅僅是把源程序劃分和整理成一個個的段(phase),並不進行編譯。

  • 預處理器在UNIX傳統中通常縮寫爲PP,在自動構建腳本中C預處理器被縮寫爲CPP的宏指代。爲了不造成歧義,C++(c-plus-plus) 經常並不是縮寫爲CPP,而改成CXX。


C語言預處理符號

ANSI C標準要求支持的預處理符號包括:

#define、#undef(宏定義), #include(文件包含), #if、#else、#elif、#endif、#ifdef、#ifndef(條件編譯), #line(行控制), #error(錯誤處理), #pragma(實現相關), #(轉義),##(參數連接)。


宏定義的注意事項

試圖使用宏去定義註釋符號是不行的,例如以下代碼:

    #define BSC //
    #define BMC /*
    #define EMC */
    BSC my single-line comment
    BMC my multi-line comment EMC


因爲註釋先於預處理指令處理,當展開這些宏定義的時候自然會出現一堆錯誤。

宏定義表達式的時候一定不能吝嗇括號這個不用解釋了。

宏定義的時候宏名中最好不要有空格。下面的定義會帶來很多麻煩:

    #define SUM (x) ((x)*(x))

一旦使用了#undef撤銷宏,則後面的代碼都不能使用這個宏,除非再次定義。此外,如果沒有#undef的情形下就直接再次定義,後來的定義會覆蓋掉前面的定義。下面代碼中的c值是4:

    #include <stdio.h>

    #define X 3
    #define Y X*2
    #undef X
    #define X 2

    int c = Y;

    int main(int argc, char** argv){
        printf("%d",c) ;
        return 0;
    }

宏僅在使用的時候展開,否則即使定義有問題,也不會編譯出錯。如果把上面代碼中的第二個#define註釋掉,並把C的值賦值爲0,即撤銷了X定義,也不會報錯,因爲沒有使用Y,也就不會展開。


#pragma的常用參數

message:用於在編譯窗口輸出信息中顯示對應信息。下面是一個典型的應用:

    #ifdef _X86
        #pragma message("x86 macro is activated.");
    #endif

code_seg:在開發驅動程序的時候會用到。

once: 指定(確保)僅編譯一次該文件(一般是頭文件)。

hdrstop:表示不編譯後面的頭文件。

pack:指定內存對齊參數。


#符號和##符號

#符號用於轉義。這麼說起來不好理解,看例子:

    #define PRTSQR(x) printf("The sqr of x is %d.\n", ((x)*(x)));

如果執行PRTSQR(4),則這句代碼的輸出是:

The sqr of x is 16.

如果希望顯示參數的值,那麼在字符串中的字符x前面加一個#並加一個引號,即:

    #define PRTSQR(x) printf("The sqr of "#x" is %d.\n", ((x)*(x)));

輸出結果就成了:

The sqr of 4 is 16.


##運算符用於連接,例如下面的宏:

    #define XNAME(n) x##n
    int XNAME(8);

上面的第二行代碼會被展開爲x8。


關於預處理符號先總結到這裏。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章