網路城邦
上一篇 回創作列表 下一篇   字體:
Preprocessor
2009/09/17 23:08:18瀏覽6562|回應0|推薦1
如果某展場要舉辦大型的博覽會,抑或某公司要舉辦新產品發表會,則必定有一大堆事前的準備工作需要去執行,像這種「事前的準備工作」,正是preprocessor 的主要工作內容。

就程式的編譯而言,preprocessor 負責處理編譯之前的準備工作,其主要的三個工作項目為:一、引入 inclusion file 的內容;二、處理 conditional compilation;三、將 macro 代換成 code snippet。除此之外,preprocessor 還處理其他的瑣碎事項,例如將 comment 代換成一個 space,將 back slash 所連接
的 continuation line 轉換成單一的 logical line 等等。

Directives

顧名思義,directive 是指經由官方所授權的命令 (指示),下級單位接到此種正式的命令,就得確實地去執行。對 preprocessor 而言,我們 (程式的設計者) 就是下達命令的官方,而它就是負責執行的下級單位,但是我們所能下達的命令僅限於 C 語言所設計規範的十二個 directive,不能自行定義新的命令。下列所示即為 preprocessor 所能接受的 directive:

#defi ne #endif #ifdef #line
#elif #error #ifndef #pragma
#else #if #include #undef

請留意所有的 directive 都是以 # 做為開頭的。此外,還有一個叫做 defined 的construct 可以和 #if 以及 logical operator 搭配使用。

Inclusion of Header Files

我們經常見到許多程式的一開頭就是 "#include ",而它就是一個 inclusion of header file,其所代表的意思是:命令 preprocessor 將 stdio.h 的檔案內容全部拷貝到目前的程式檔案之中,而該 #include 的所在位置就是拷貝內容的置入起點。此 include directive 的語法如下:

#include token-sequence

而常見的寫法則為:

#include
#include "header-fi le-name"

其中的第一種寫法 ,表示該 header file 是位於系統的標準目錄之內,例如 /usr/include 就是 Unix 系統放置 header file 的標準目錄;第二種寫法 "header-file-name",表示該 header file 與 source file 都放在同一個目錄之下。在此順道一提 header file 名稱的由來。因為 #include 或 #include "file" 經常被寫在原始程式檔的開頭 (head of the source file),所以這些 file (例如 stdio.h、stdlib.h 等) 才被通稱為 header file。

Conditional Compilation

當應用程式需要偵錯、追蹤或移植到其他平台時,conditional compilation 就可以幫很大的忙,因為程式設計者可以透過它來選擇不同的客製化程式碼。為了完成 conditional compilation 而必定會使用到的 directive 有:

#ifdef #ifndef #if #else #elif #endif

其中 #ifdef 的意義為 if defined;#ifndef 的意義為 if not defined;#elif 的意義為 else if。當 #if 和 defined 相互搭配時,亦可造出與 #ifdef 以及 #ifndef 的等義敘述。例如:

#if defined(identifier)
is equivalent to
#ifdef identifier

#if !defined(identifier)
is equvilant to
#ifndef identifier

讀者可能會有此疑問:「既然等義,為什麼還要還發明 defined(identifier) 這個 construct ?」此因 defined(identifier) 可以搭配 logical operator (&&、| |、!) 做更為複雜的表述,這是 #ifdef 與 #ifndef 做不到的。除了 conditional compilation 之外,把 "#if 0" 用來將某些程式碼點掉 (comment it out),也是蠻常見到的另類用法。例如:

#if 0
...... The code is commented out!......
#endif

偵錯或追蹤程式碼

現今的應用程式,幾乎都含有 conditional compilation 的程式碼,其中最常見的用法就是用於偵錯。例如:

1: #ifdef DEBUG
2: /* customized code for debugging */
3: ......;
4: printf(......);
5: ......;
6: #endif

上述程式碼的意思為:如果 DEBUG 有定義,則將 line 2 至 5 的程式碼視為有效的程式碼;如果 DEBUG 沒有定義,則將 line 2 至 5 的程式碼視為無效的程式碼。其中的 DEBUG 可在程式中透過 #define 來做定義,抑或在編譯時透過–D option 來加以定義。例如:

gcc -c -DDEBUG xxx.c

平台的移植

conditional compilation 另外一種常見的應用就是用於平台的移植 (platform porting)。例如我們想將應用程式由 Intel X86 平台移植到 Sun Sparc 平台,因此應用程式的部分程式碼很可能就得依平台來作修改,此時這些需要客製化的程式碼可寫成:

#ifdef INTEL_X86
......
......
#elif SUN_SPARC
......
......
#endif
( 創作其他 )
推薦文章 列印 加入我的文摘
上一篇 回創作列表 下一篇

引用
引用網址:https://classic-blog.udn.com/article/trackback.jsp?uid=chungchia&aid=3327025