C語言的預編譯

2021-05-27 08:19:53 字數 2974 閱讀 2700

預編譯指令基本分類如下

類別指令

預定義符號

__file__、__line__、__date__、__time__、__stdc__

巨集#define

檔案包含

#include

條件編譯

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

還有一些指令,名稱和功能如下表:

指令功能

#空指令

#undef

移除乙個空定義

#error

停止編譯,並生成錯誤資訊

#line

修改__line__和__file__的值

#progma

允許編譯器提供額外功能

在定義巨集的時候,有兩個運算子

運算子功能

#將巨集引數轉換為字串

##將多個符號連線成乙個識別符號

1. 一般在巨集定義的結尾不加分號。

我們在使用的時候,要加上分號,像我們平時寫語句一樣。

2. 注意加括號。

在有引數的空定義中,如果含有數值運算,那麼就要在「巨集整體」和「巨集引數」兩端都要加上括號。

如:#define max(a, b) ((a)+(b)); 

3. 注意空格。

在有引數的巨集定義中,注意「巨集名稱」和「引數列表」之間不能有空格

如:#define max (a, b) ((a)+(b));  在"max」和」(a, b)」之間不能有空格。

4. 不要使用有***的引數區呼叫巨集。

常見的有***的引數有:a++,getchar()等。

如:巨集定義為#define max (a, b) ((a)+(b));  那麼使用max(i++, j++)呼叫該巨集,會造成 i 或 j 中的乙個值增加2,而不是我們期望的 1。

5. 可以使用編譯器選項 新增巨集 和 移除巨集。

我使用的是gcc,新增巨集的指令是」-d」,移除巨集的指令是」-u」。

6. 巨集引數替換的時候,不會替換字串中的字元。

即不會替換雙引號之間的字元,其他的都會被替換,包括單引號之間的。

7. 可以使用#將巨集引數的值轉化為字串。

直接使用#,是將巨集引數的名稱轉化為字串。利用下面的技巧(增加乙個過渡巨集),可以將「巨集引數的值」轉化為字串(當巨集引數有值時,這時的巨集引數常常也是乙個巨集)。

#include #include #define number ten /* 巨集名稱為number,巨集的值為ten */ #define str(x) #x #define xstr(x) str(x) /* 增加的乙個 過渡巨集 */ int main()
輸出結果為:

str(number) == number xstr(number) == ten
8. 使用##運算子來實現識別符號連線。

不過,不建議使用操作符##來連線識別符號,因為這個容易是程式可讀性大大降低。

1. 要將標頭檔案的定義在保護條件中。

目的是為了防止重複包含標頭檔案。如果你檢視過gcc或者其他編譯器的源**,你一定對這個非常熟悉。

例如,你要編寫乙個標頭檔案,myheader.h,那麼你的標頭檔案的內容形式應該為:(定義乙個_myheader巨集)

#ifndef _myheader #define _myheader 1 /* 中間是你的標頭檔案內容 */ #endif /* _myheader */
2. 注意windows系統和unix系統的路徑符號不同。

可以再#include中指定路徑來包含檔案,例如 #include 「../head.h」。但是注意,windows中使用反斜線」/」作為路徑分隔符,而unix系統使用的是斜線」/」

3. 可以使用 編譯器選項 來設定搜尋路徑。

我使用的gcc,使用的-idir選項,例如: -i"d:/dev-cpp/include"。

1. #ifdef等價於#if defined(),#ifndef等價於#if !defined()。

2. 在#if中可以使用邏輯操作符(&&、||、!)。在#ifdef 中是不可以使用的,這也是#if的優越點。

#include #include #define a 1 #define b 0 int main()
執行結果:

test logic operation in #if
3. sizeof(int)在預編譯階段是不會被求值的。

只要知道「預編譯階段」在真正的「編譯階段」之前,就很容易理解了。預編譯階段只是對組成源**中的字元進行作用,從某種意義上來說,它有時甚至不知道它的操作物件是什麼,它只是按照既定的規則執行替換。

sizeof(int),無論是sizeof的解析,還是型別的解析,都是在「編譯階段」才開始的,編譯階段知道它的操作物件是什麼。

下面的**是錯誤

#if sizeof(int) == 2 printf("precompile sizeof(int)"); #endif
把乙個預處理指令寫成多行的形式,要使用符號」/」,並且在該符號後面應緊跟換行符。而非預處理指令**行不需要使用該符號,直接換行即可。 原因:編譯階段會自動忽略空白符,而預編譯階段不會。

C語言的預編譯

technorati 標籤 c,預編譯,巨集,檔案替換,條件編譯 由 源 到 可執行檔案 的過程包括四個步驟 預編譯 編譯 彙編 鏈結。所以,首先就應該清楚的首要問題就是 預編譯只是對程式的文字起作用,換句話說就是,預編譯階段僅僅對源 的單詞進行變換,而不是對程式中的變數 函式等。預編譯指令的基本知...

C語言的預編譯

預處理功能主要包括巨集定義,檔案包含,條件編譯三部分。分別對應巨集定義命令,檔案包含命令,條件編譯命令三部分實現。預處理過程讀入源 檢查包含預處理指令的語句和巨集定義,並對源 進行響應的轉換。預處理過程還會刪除程式中的注釋和多餘的空白字元。預處理指令是以 號開頭的 行。號必須是該行除了任何空白字元外...

c語言中預編譯

預編譯又被稱為預處理,是做 文字的替換工作。處理 開頭的指令。就是為編譯做預備工作的準備。常見的預編譯指令有三種 1 include指令 該指令指示編輯器將 檔案的全部內容插入此處,如果使用 代表在系統指定目錄下搜尋檔案,使用 代表現在當前目錄下搜尋檔案,然後在系統預設目錄下搜尋。2 define指...