以符號「#」開頭的命令,如:
#define n 10;
#define
這些命令不是c語言本身的組成部分,而是由c編譯系統提供的。在通常的編譯(詞法和語法分析、**生成、優化等)之前,編譯系統要預先對這些命令進行處理,因此稱為「編譯預處理」命令。編譯預處理可以改善程式設計環境,提高程式設計效率,有助於編寫易移植、易除錯的程式,是c語言的特色內容之一。
c編譯系統的預處理功能主要包括巨集的處理、檔案包含的處理、條件編譯的處理三種。所有預處理命令均以「#」開始,末尾不加分號,以區別於一般的c語句。
#include
#define pi 3.14159
intmain()
上述程式中「#define pi 3.14159」就是乙個巨集定義,pi稱為巨集名,其作用是用識別符號pi代替3.14159,稱為巨集引用。預處理時,程式中的pi將被所定義的串3.14159替換,稱為巨集展開或巨集替換。
巨集可分為兩種形式:不帶引數的巨集和帶引數的巨集。
不帶引數的巨集定義,其一般形式為:
#define 識別符號 一串字元
其作用是用識別符號代替其後一串字元。識別符號習慣上使用大寫字母,一串字元為任意字元組成的字串行,除非是表示乙個字串常量,一般不用雙引號括起。
說明:1.巨集定義的前後應有空格,以便準確地識別巨集名。
2.巨集定義是用巨集名代替乙個字串行,是一種簡單的替換,不進行正確性檢查。
例如:
#define pi 3.l4l59
這裡數字1誤寫成了l預處理時也原樣代入,編譯時巨集展開後的語句是錯誤的,會提示報錯。
3.在一串字元中如果出現運算子,要注意巨集展開後的結果。通常可以在所定義字串行的適當位置加括號來避免一些運算上的錯誤。
例如:
#define pi 2+1.14159..
.s=pi*r*r;
這裡巨集展開後「s=2+1.14159rr;」,運算結果顯然是錯誤的。應將巨集的定義寫為「#define pi (2+1.14159)」,這時的運算結果才是正確的。
4.在巨集定義的一串字元中,可以引用已定義的巨集名,稱為巢狀巨集定義。
例如:
#include
#define pi 3.14159
#define r 3.0
#define area pi*r*r
intmain()
5.若用雙引號引起來的字串常量**現了與巨集名相同的內容,不能將其理解為巨集名,更不能展開。
例如:
#define pi 3.14159
void
main()
這裡前乙個pi是字串的一部分,後乙個pi才是巨集名。
6.巨集名也有其作用範圍,即作用域。巨集名的作用域是從定義點開始到本遠檔案結束或用預處理命令#undef取消定義之前。
帶引數的巨集定義是對不帶引數巨集定義的擴充,它不是進行簡單的字串替換,而是還要進行引數替換。帶引數巨集定義的一般形式為:
#define 識別符號(形參表) 一串字元
其作用是用識別符號代表一串字元。識別符號習慣上是用大寫字母。形參表為用逗號分隔的若干個識別符號。一串字元為任意字元組成的字串行,其中包含形參中指定的識別符號。
巨集引用的一般形式為:
巨集名(實參表)
其中,引數一般是程式中已宣告的變數或表示式。
預處理時,程式中所有的巨集引用「巨集名(實參表)」替換成對應的一串字元。
例如:
#include
#define area(r) 3.14159*(r)*(r)
//定義帶引數的巨集,r是形參
void
main()
1.帶引數的巨集展開時,是用巨集引用中的實參字串替換巨集定義時一串字元中的形參。
上例中將「s=area(r);」改為「s=area(r+10);」巨集展開後「s=3.14159*(r+10)* (r+10);」
如果將
#define area(r) 3.14159*(r)*(r)
改為
#define area(r) 3.14159*r*r
則語句
「s=area(r+10);」 巨集展開後「s=3.14159*r+10 *r+10;」將產生錯誤。
所以定義帶引數的巨集時,應將一串字元中的引數加上括號。2.在定義帶引數的巨集時,巨集名與後面的圓括號之間不能有空格,否則將空格之後的內容都將作為代替字串的一部分。
例如:
#define m(a,b) ((a)>(b)?(a):(b))
//替代部分((a)>(b)?(a):(b))
#define m (a,b) ((a)>(b)?(a):(b))
//替代部分(a,b) ((a)>(b)?(a):(b))
3.巨集引用和函式呼叫形式上相似,但要注意巨集引用與函式呼叫的區別。
巨集函式是另一種巨集定義的應用,巨集函式定義時要在換行處加「\」,不換就不需要,末尾不需要加「\」。
#define pressenter\
/*#define pressenter {printf("press enter...");getchar();fflush(stdin);與上面的效果是一樣的*/
這是乙個實現暫停程式,按回車鍵繼續的巨集函式定義大家可以通過這篇文章中c語言實現的**去具體了解它在程式中的使用
巨集函式一般用於定義乙個在程式中運用重複次數較多的函式,可以簡化**,減少執行時間。但是由於巨集函式是直接引用的,不會對函式進行驗證,還有沒有對應的返回值。
預處理 01 無參巨集定義
在之前,已多次使用過以 號開頭的預處理命令。如包含命令 include 巨集定義命令 define pi 3.1415926等。在源程式中這些命令都放在函式之外,而且一般都放在原始檔的前面,它們稱為預處理部分。1.無參巨集定義 無參巨集的巨集名後不帶引數。其定義的一般形式為 define 識別符號 ...
C語言 有參巨集
說明 紅色箭頭表示的意思是 巨集展開 形參用實參換,其它字元保留 巨集體及各形參外一般應加括號 如 1 帶參巨集定義的一般格式 define 巨集名 形參表 語言符號字串 2 帶參巨集的呼叫和巨集展開 1 呼叫格式 巨集名 實參表 2 巨集展開 用巨集呼叫提供的實參字串,直接置換巨集定義命令列中 相...
C語言 有參巨集
說明 紅線的意義 巨集展開 形參用實參換,其它字元保留 巨集體及各形參外一般應加括號 1 帶參巨集定義的一般格式 define 巨集名 形參表 語言符號字串 2 帶參巨集的呼叫和巨集展開 1 呼叫格式 巨集名 實參表 2 巨集展開 用巨集呼叫提供的實參字串,直接置換巨集定義命令列中 相應形參字串,非...