1. 程式人生 > >linux c 之 條件編譯

linux c 之 條件編譯

1. 正確的遮蔽一段程式碼

 #if 0  // 如果if 後面的是 0 ,遮蔽掉以下一段程式碼,如果是1 ,使用以下一段程式碼。

XXXXXXXXXXX

 #endif

2. 巨集定義指令

      巨集定義了一個代表特定內容的識別符號。預處理過程會把原始碼中出現的巨集識別符號替換成巨集定義時的值。巨集最常見的用法是定義代表某個值的全域性符號。巨集的第二種用法是定義帶引數的巨集(巨集函式),這樣的巨集可以象函式一樣被呼叫,但它是在呼叫語句處展開巨集,並用呼叫時的實際引數來代替定義中的形式引數。

#define MAX_NUM 10  //(只是簡單的替換)
 
3. 條件編譯指令。

      程式設計師可以通過定義不同的巨集來決定編譯程式對哪些程式碼進行處理。條件編譯指令將決定那些程式碼被編譯,而哪些是不被編譯的。可以根據表示式的值或者某個特定的巨集是否被定義來確定編譯條件。

3.1 #if/#endif/#else/#elif指令
    #if指令檢測跟在製造另關鍵字後的常量表達式。如果表示式為真,則編譯後面的程式碼,知道出現#else、#elif或#endif為止;否則就不編譯。
    #endif用於終止#if預處理指令。
    #else指令用於某個#if指令之後,當前面的#if指令的條件不為真時,就編譯#else後面的程式碼。

#define DEBUG       //此時#ifdef DEBUG為真//#define DEBUG 0  //此時為假int main()
{
   #ifdef DEBUG
      printf("Debugging\n");
   #else       printf("Not debugging\n");    #endif    printf("Running\n");    return0; }

3.2 #ifdef和#ifndef

這二者主要用於防止重複包含。我們一般在.h標頭檔案前面加上這麼一段:

//標頭檔案防止重複包含 //funcA.h#ifndef FUNCA_H #define FUNCA_H//標頭檔案內容#end if

這樣,如果a.h包含了funcA.h,b.h包含了a.h、funcA.h,重複包含,會出現一些type redefination之類的錯誤。
#if defined等價於#ifdef; #if !defined等價於#ifndef

4、標頭檔案包含指令。

採用標頭檔案的目的主要是為了使某些定義可以供多個不同的C源程式使用。因為在需要用到這些定義的C源程式中,只需加上一條#include語句即可,而不必再在此檔案中將這些定義重複一遍。預編譯程式將把標頭檔案中的定義統統都加入到它所產生的輸出檔案中,以供編譯程式對之進行處理。

  #include預處理指令的作用是在指令處展開被包含的檔案。包含可以是多重的,也就是說一個被包含的檔案中還可以包含其他檔案。標準C編譯器至少支援八重巢狀包含。預處理過程不檢查在轉換單元中是否已經包含了某個檔案並阻止對它的多次包含,這個的處理辦法上面已經給出。

  在程式中包含標頭檔案有兩種格式:
        #include <my.h>
        #include "my.h"
   第一種方法是用尖括號把標頭檔案括起來。這種格式告訴預處理程式在編譯器自帶的或外部庫的標頭檔案中搜索被包含的標頭檔案。第二種方法是用雙引號把標頭檔案括起來。這種格式告訴預處理程式在當前被編譯的應用程式的原始碼檔案中搜索被包含的標頭檔案,如果找不到,再搜尋編譯器自帶的標頭檔案。
   採用兩種不同包含格式的理由在於,編譯器是安裝在公共子目錄下的,而被編譯的應用程式是在它們自己的私有子目錄下的。一個應用程式既包含編譯器提供的公共標頭檔案,也包含自定義的私有標頭檔案。採用兩種不同的包含格式使得編譯器能夠在很多標頭檔案中區別出一組公共的標頭檔案。

5、特殊符號。

預編譯程式可以識別一些特殊的符號。預編譯程式對於在源程式中出現的這些串將用合適的值進行替換。

5.1 __LINE__

注意,是雙下劃線,而不是單下劃線 。
__FILE__ 包含當前程式檔名的字串
__LINE__  表示當前行號的整數
__DATE__ 包含當前日期的字串
__STDC__  如果編譯器遵循ANSI C標準,它就是個非零值
__TIME__ 包含當前時間的字串
複製程式碼//9 #include<stdio.h>int main() {    printf("Hello World!\n");    printf("%s\n",__FILE__);    printf("%d\n",__LINE__);    return0; }複製程式碼

5.2 #line等

#error指令將使編譯器顯示一條錯誤資訊,然後停止編譯。
#line指令改變_LINE_與_FILE_的內容,它們是在編譯程式中預先定義的識別符號。
#pragma指令沒有正式的定義。編譯器可以自定義其用途。典型的用法是禁止或允許某些煩人的警告資訊。

複製程式碼 //例10,#line舉例#line 100          //初始化行計數器 #include<stdio.h>//行號100int main() { printf("Hello World!\n"); printf("%d",__LINE__); return0; } //輸出104 複製程式碼

總結:預編譯程式所完成的基本上是對源程式的“替代”工作。經過此種替代,生成一個沒有巨集定義、沒有條件編譯指令、沒有特殊符號的輸出檔案。這個檔案的含義同沒有經過預處理的原始檔是相同的,但內容有所不同。下一步,此輸出檔案將作為編譯程式的輸出而被翻譯成為機器指令。