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

關於預處理的「常識」
ide

  • 預處理並非編譯,也不是「預編譯」。spa

  • 預處理並非每一個語言都有的。code

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

  • 預處理器在UNIX傳統中一般縮寫爲PP,在自動構建腳本中C預處理器被縮寫爲CPP的宏指代。爲了避免形成歧義,C++(c-plus-plus) 常常並非縮寫爲CPP,而改爲CXX。開發


C語言預處理符號字符串

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

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


宏定義的注意事項編譯

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

    #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。


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

相關文章
相關標籤/搜索