程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言之預處理

C語言之預處理

編輯:關於C語言

引言:學C語言之初,一提到預處理,腦子裡想到的就是#define的宏定義以及#include包含的頭文件。後來隨著對C的深入學習發現,預處理不止這些。比如條件編譯、預定義的宏等等。下面對此進行總結。

先給出預處理的定義:在編譯程序之前,先由預處理器檢查程序(因此稱為預處理器),根據程序中使用的預處理器命令,預處理器用符號縮略語所代表的內容替換程序中的縮略語。

1. #define

最常用的預處理器命令就是define命令,該預處理器命令有三部分組成:#define本身、符號縮略語、替換列表(或稱為主體)。

結構可寫為:#define 宏 主體 其中宏部分不能有空格,只能是數字、下劃線、字母,但第一個字符不能使數字。

如:#define PX printf("x is %d.\n", x)

預處理器發現程序中的宏後,會用它的等價替換文件代替宏。如果該字符串中還包括宏,則繼續替換這些宏。如果宏出現在雙引號中,則不做替換。如果在雙引號中出現的宏前面有“#運算符”,則可以用宏參數創建字符串。如:

#define PSQR(X) printf("The square of X is %d.\n", ((X)*(X)))

PSQR(8) //等價於printf("The square of X is %d.\n", ((8)*(8))),輸出The square of X is 64.

#define PSQR(X) printf("The square of "#X" is %d.\n", ((X)*(X)))

PSQR(8) //等價於printf("The square of 8 is %d.\n", ((8)*(8))),輸出The square of 8 is 64.

小結:引號中的字符中中的X被看作普通文本,而不是被看作一個可替換的語言符號。#符號用作一個預處理運算符,它可以把語言符號轉化為字符串。


預處理器的粘合劑:##運算符。和上面的#運算符一樣,##運算符可以用於類函數宏的替換部分。##還能用於類對象宏的替換部分,把兩個符號組合成單個語言符號,如:

#define XNAME(n) x##n

XNAME(4) //等價於x4


從宏的定義和使用可以看出,它與函數非常相近,但宏與函數又有所不同,他們的選擇實際上是時間和空間的權衡。宏產生內聯代碼,也就是說在程序中產生語句。如果使用宏20次,則會把20行代碼插入程序中,如果使用函數20次,那麼程序中只有一份函數的語句拷貝,因此節省了空間。另一方面,程序的控制必須轉移到函數中並隨後返回調用程序,因此這比內聯代碼話費的時間多。


2.#include

預處理器發現#include指令後,就會尋找後跟的文件名並把這個文件的內容包含到當前文件中。被包含文件的文本將替換源代碼文件中的#include指令,就像把被保護文件中的全部內容鍵入到源文件中的這個特定位置一樣。

#include // 文件放在尖括號中,搜索系統工作目錄

#include “name.h” // 文件名放在雙引號中,搜索當前工作目錄

#include "/dir1/dir2/name.h" // 搜索/dir1/dir2目錄

頭文件中一般包含的內容有:明顯常量、宏函數、函數聲明、結構體模板定義、類型定義


3. 其他指令

#undef指令取消前面的#define定義。#if #ifdef #ifndef #else #elif #endif指令可用於選擇什麼情況下編譯哪些代碼。#line指令用於重置行和文件信息,#error指令用於給出錯誤消息,#param指令用於想編譯器發出指示


4. 預定義的宏:

__DATE__ : 進行預處理的日期

__FILE__ :代碼當前源代碼文件名的字符串文字

__LINE__ :代表當前源代碼文件中的行號的整數常量

__STDC__ :設置為1時,表示該實現遵循C標准

__TIME__ : 源文件編譯時間

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved