C中預編譯

C中預編譯詳解  

 預處理過程掃描源代碼,對其進行初步的轉換,產生新的源代碼提供給編譯器。可見預處理過程先於編譯器對源代碼進行處理。
在C 語言中,並無任何內在的機制來完成以下一些功能:在編譯時包含其餘源文件、定義宏、根據條件決定編譯時是否包含某些代碼。要完成這些工做,就須要使用預處理程序。儘管在目前絕大多數編譯器都包含了預處理程序,但一般認爲它們是獨立於編譯器的。預處理過程讀入源代碼,檢查包含預處理指令的語句和宏定義,並對源代碼進行響應的轉換。預處理過程還會刪除程序中的註釋和多餘的空白字符。

  預處理指令是以#號開頭的代碼行。#號必須是該行除了任何空白字符外的第一個字符。#後是指令關鍵字,在關鍵字和#號之間容許存在任意個數的空白字符。整行語句構成了一條預處理指令,該指令將在編譯器進行編譯以前對源代碼作某些轉換。下面是部分預處理指令:函數

        指令              用途
         #                  空指令,無任何效果
         #include      包含一個源代碼文件
         #define        定義宏
         #undef         取消已定義的宏
         #if               若是給定條件爲真,則編譯下面代碼
         #ifdef          若是宏已經定義,則編譯下面代碼
         #ifndef        若是宏沒有定義,則編譯下面代碼
         #elif            若是前面的#if給定條件不爲真,當前條件爲真,則編譯下面代碼,至關於#elseif
         #endif         結束一個#if……#else條件編譯塊
         #error        中止編譯並顯示錯誤信息
spa

  1、文件包含
        #include預處理指令的做用是在指令處展開被包含的文件。包含能夠是多重的,也就是說一個被包含的文件中還能夠包含其餘文件。標準C編譯器至少支持八重嵌套包含。
        預處理過程不檢查在轉換單元中是否已經包含了某個文件並阻止對它的屢次包含。這樣就能夠在屢次包含同一個頭文件時,經過給定編譯時的條件來達到不一樣的效果。例如:debug

 #define AAA
        #i nclude "t.c"
        #undef AAA
        #i nclude "t.c"字符串

        爲了不那些只能包含一次的頭文件被屢次包含,能夠在頭文件中用編譯時條件來進行控制。例如:
       
        #ifndef MY_H
        #define MY_H
          ……
        #endif
編譯器

        在程序中包含頭文件有兩種格式:
        #i nclude <my.h>
        #i nclude "my.h"
         第一種方法是用尖括號把頭文件括起來。這種格式告訴預處理程序在編譯器自帶的或外部庫的頭文件中搜索被包含的頭文件。第二種方法是用雙引號把頭文件括起來。這種格式告訴預處理程序在當前被編譯的應用程序的源代碼文件中搜索被包含的頭文件,若是找不到,再搜索編譯器自帶的頭文件。io

2、宏
      
  宏定義了一個表明特定內容的標識符。預處理過程會把源代碼中出現的宏標識符替換成宏定義時的值。宏最多見的用法是定義表明某個值的全局符號。宏的第二種用法是定義帶參數的宏,這樣的宏能夠象函數同樣被調用,但它是在調用語句處展開宏,並用調用時的實際參數來代替定義中的形式參數。
    1.#define指令
        #define預處理指令是用來定義宏的。該指令最簡單的格式是:首先聲明一個標識符,而後給出這個標識符表明的代碼。在後面的源代碼中,就用這些代碼來替代該標識符。
宏表示的值能夠是一個常量表達式,其中容許包括前面已經定義的宏標識符。例如:
            #define ONE 1
            #define TWO 2
            #define THREE (ONE+TWO)
        注意上面的宏定義使用了括號。儘管它們並非必須的。但出於謹慎考慮,仍是應該加上括號的。
編譯

 

3.#運算符
        出如今宏定義中的#運算符把跟在其後的參數轉換成一個字符串。有時把這種用法的#稱爲字符串化運算符。例如:class

            #define PASTE(n) "adhfkj"#n搜索

            main()
            {
               printf("%s\n",PASTE(15));
            }
        宏定義中的#運算符告訴預處理程序,把源代碼中任何傳遞給該宏的參數轉換成一個字符串。因此輸出應該是adhfkj15。bug


    4.##運算符
        ##運算符用於把參數鏈接到一塊兒。預處理程序把出如今##兩側的參數合併成一個符號。看下面的例子:

            #define NUM(a,b,c) a##b##c
            #define STR(a,b,c) a##b##c

            main()
            {
                printf("%d\n",NUM(1,2,3));
                printf("%s\n",STR("aa","bb","cc"));
            }

        最後程序的輸出爲:
                 123
                 aabbcc
 

3、條件編譯指令
    條件編譯指令將決定那些代碼被編譯,而哪些是不被編譯的。能夠根據表達式的值或者某個特定的宏是否被定義來肯定編譯條件。
    1.#if指令
        #if指令檢測跟在其後的宏或表達式是否爲真。若是表達式爲真,則編譯後面的代碼,知道出現#else、#elif或#endif爲止;不然就不編譯。

    2.#endif指令
        #endif用於終止#if預處理指令。

            #define DEBUG 0
            main()
            {
                #if DEBUG
                    printf("Debugging\n");
                #endif
                    printf("Running\n");
            }

        因爲程序定義DEBUG宏表明0,因此#if條件爲假,不編譯後面的代碼直到#endif,因此程序直接輸出Running。
        若是去掉#define語句,效果是同樣的。


    3.#ifdef和#ifndef
        #define DEBUG

         main()
        {
            #ifdef DEBUG
                printf("yes\n");
            #endif
            #ifndef DEBUG
                printf("no\n");
            #endif
        }
        #if defined等價於#ifdef; #if !defined等價於#ifndef


    4.#else指令
        #else指令用於某個#if指令以後,當前面的#if指令的條件不爲真時,就編譯#else後面的代碼。#endif指令將中指上面的條件塊。

        #define DEBUG

        main()
        {
            #ifdef DEBUG
                printf("Debugging\n");
            #else
                printf("Not debugging\n");
            #endif
                printf("Running\n");
       }

 

    5.#elif指令
        #elif預處理指令綜合了#else和#if指令的做用。

        #define TWO

        main()
        {
            #ifdef ONE
                printf("1\n");
            #elif defined TWO
                printf("2\n");
            #else
                printf("3\n");
            #endif
        }
        程序很好理解,最後輸出結果是2。

     6.其餘一些標準指令        #error指令將使編譯器顯示一條錯誤信息,而後中止編譯。        #line指令能夠改變編譯器用來指出警告和錯誤信息的文件號和行號。        #pragma指令沒有正式的定義。編譯器能夠自定義其用途。典型的用法是禁止或容許某些煩人的警告信息。

相關文章
相關標籤/搜索