2015年2月28日 星期六

C/C++ - 預編譯 Precompilation

 

常常在別人的C程式碼中看到#Define DEBUG這種用法,興致一來把這個小洞補一下順便學習一下相關知識:)


預編譯(Precompilation)
主要是為編譯做的預備工作的階段(處理#開頭的預編譯指令),例如#include(拷貝代碼)、#define(定義替換)、條件編譯等。
以下是一些預編譯指令簡介。

1.   #include指令
#include <AAA.h> : 預處理程序會尋找在系統默認目錄或括號內的路徑,通常用於系統header。
#include "BBB.h" : 預處理程序會在所在目錄查找,沒找到的話才用第一種方法尋找。

2.   #define、#undef指令
#define: 用於定義替換的符號
#undef : 取消之前define的定義
#define PI 3.14
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
 cout << PI << endl;   //3.14
 cout << MAX(2, 3) << endl;  //3
#undef PI
 //cout << PI << endl; //compile error

[註] define後#符號的用法:
#:把跟在其後的參數轉換成一個string。
##:把出現在##兩側的參數合並成一個string。
#define CAT(n) "ABC"#n
 cout << CAT(123) << endl;  //ABC123

#define NUM(a,b) a##b
#define STR(a,b) a##b
 cout << NUM(1, 2) << endl;  //12
 cout << STR("Hello", "World") << endl; //HelloWorld

3.   條件編譯(Conditional Compilation)指令
在C語言中,前置處理器依照指定條件進行條件編譯(Conditional Compilation),也就是決定哪些代碼被編譯,哪些不被編譯,常用條件編譯進行確認變數內容的除錯工作。

#if、#else、#elif和#endif指令 : 跟一般的if、else if、else語句類似
#ifdef和#ifndef : 如果在此之前已/未定義,則編譯。
//example 1
#define OPTION 1
...
#if OPTION == 1
 cout << "Option: 1" << endl;
#elif OPTION == 2
 cout << "Option: 2" << endl; //選擇這句
#else
 cout << "Option: Illegal" << endl;
#endif

//example 2
#define DEBUG //定義DEBUG巨集
...
#ifdef DEBUG //如果DEBUG巨集已經定義,#ifdef、#endif之間的敘述就會被編譯
    printf("RUNNING DEBUG BUILD");
#else
    printf("Running... this is a release build.");
#endif

4.   #line指令
C語言中可以
使用__FILE__表示本行語句所在源文件的文件名
使用__LINE__表示本行語句在源文件中的位置
而#line指令可以重新設定這兩個變量的值,其語法格式為 #line number ["filename"]

5.   #error
#error指令在編譯時輸出編譯錯誤訊息方便除錯。

6.   #pragma指令
該指令用來來設定編譯器的狀態或者是指示編譯器完成一些特定的動作,它有許多不同的參數。


Reference :
http://www.codingunit.com/cplusplus-tutorial-preprocessor-directives
http://noalgo.info/417.html







技術提供:Blogger.