有趣的C語言預處理

2021-06-28 21:50:28 字數 1541 閱讀 2701

分類解釋

在編譯器編譯之前,會首先搜尋預處理指令,按照指令完成編譯,預處理又分為:檔案包含、條件編譯、布局控制(雜注)和巨集替換。

檔案包含

#include""和#include<>,前者是和該c檔案相同目錄下的.h,如 #include "os_cfg.h" ,或指明路徑的.h,如 #include "\software\ucos-ii\source\ucos_ii.h" ;

後者是編譯器系統路徑中的.h,一般c語言標準庫函式在編譯器裡整合,如 #include 。

只要包含了.h,而.h裡有函式宣告(或變數、結構體例項),那麼不論這個函式(變數、結構體例項)在那個.c檔案裡定義的,都可以在主c檔案中使用。

對於函式,可以按功能分類成各種模組,集合在一起寫成乙個.c檔案,然後作同名的.h給出函式宣告,如果模組太多,也可以再用乙個.h來包含各模組的.h,ucos-ii中的includes.h就是這樣。

對於變數,c模組中的全域性變數只對該模組有效,如果想要被其他c檔案訪問,就得在.h裡宣告,如果主c包含了這個.h,那麼此變數就成了真正全域性的了。

對於結構體例項,其結構的定義可以放在.h裡,(如果不需要到處定義很多例項放在c裡也可以),例項定義在c裡,而宣告放在.h裡,這樣就到處可用此例項了。

#include 的物件直接被插入到了該位置,所以可能出現#include重複甚至巢狀,用#ifndef...#define...**...#endif的方法可以保證重複包含的.h那個只在第一次出現時編譯.

條件編譯:

上面的#ifndef就是條件編譯的一種。條件編譯主要用於跳過某些**不編譯,這樣可以用來寫乙個c檔案,但是適應不同硬體版本,或者可採用不同演算法。我就經常用多種演算法寫同乙個功能,#define method 1,#if methof==1...#endif, #if method ==2...#endif

protothread的神奇功能就是用巨集和條件編譯來實現的。舉個例子:

#define     lc_init(s)   s = 0;

#define     lc_resume(s)   switch(s)   

#define     pt_begin(pt)

編譯器會自動給中斷函式指定中斷向量。

巨集替換

巨集函式其實可以巧妙的代替函式,尤其是很短又沒有區域性變數的一些語句,還可以代換很多複雜的格式,如

#define f "%6.2f"

#define f3 f "\t" f "\t" f"\t\n"

用函式printf(f3,a,b,c),可以同時指定a,b,c 的格式

其他:預定義識別符號

為了處理一些有用的資訊,預處理定義了一些預處理識別符號,雖然各種編譯器的預處理識別符號不盡相同,但是他們都會處理下面的4種:

__file__ 正在編譯的檔案的名字

__line__ 正在編譯的檔案的行號

__date__ 編譯時刻的日期字串,例如: "25 dec 2000"

__time__ 編譯時刻的時間字串,例如: "12:30:55"

C語言預處理

c語言中編譯預處理的三種形式的命令 巨集定義,檔案包含,條件編譯命令。1 巨集定義主要是 define,undef 如下 define pi 3.1415926 不帶引數的巨集定義 define max a,b a b?a b 帶引數的巨集定義 說明 巨集定義在c語言與c 語言中是相通的。下面舉例說...

C語言預處理

預處理 系統自動自動呼叫預處理程式對程式中 號開頭的預處理部分進行處理,處理完畢後可以進城源程式的編譯階段。預定義 一些預定義符號 常用於除錯 file 正在預編譯的源檔名 line 當前行號 只有這個是整數常量,其他是字串常量 function 當前所在函式名 date 當前日期 time 當前時...

c語言預處理

預處理可以包含 1 巨集定義指令 2 標頭檔案包括指令 3 條件編譯指令 4 編譯程式可以識別的特殊符號 巨集定義 define undef 檔案包含 include 條件編譯 if ifdef else elif endif等 其他 line error program等 注意事項 1 在c語言中...