C 編譯預處理

2021-10-21 03:56:43 字數 3259 閱讀 5996

c++的預處理是編譯器在編譯源程式之前,先由預處理器處理預處理指令,由於在c++源程式中有各種編譯命令,而這些編譯命令由於是在程式被正常編譯之前執行的,故稱為預處理命令(或指令)。預編譯命令用來擴充c++程式設計的環境,使得程式書寫變得更加簡練和清晰。

c++提供的預處理功能主要有以下3種:

巨集定義命令。

檔案包含命令。

條件編譯命令。

為了與一般c++語句相區別,編譯預處理命令以符號#開頭,並且末尾不包含分號。習慣上編譯命令都是放在程式的開頭。

巨集定義命令是將乙個識別符號定義為乙個字串,該識別符號被稱為巨集名,被定義的巨集定義串稱為替換文字。巨集定義命令有兩種格式:即簡單的巨集定義,和帶引數的巨集定義

巨集定義的一般形式如下:

#define巨集名 字元 //其中: define是巨集定義的關鍵字,「巨集名」是需要替換的識別符號,「字串」是被指定用來替換的字串行。例如:#define pi 3.1415926;//程式中可以使用識別符號pi,編譯預處理後產生乙個中間檔案,檔案中所有pi都被替換為3.1415926說明:

(1)#define、巨集名和字串之間一定要有空格。

(2)巨集名一般用大寫字母表示,以區別於普通識別符號。

(3)巨集被定義以後,一般不能再重新定義。但可以用#undef來終止巨集定義。

(4)乙個定義過的巨集名可以用來定義其他新的巨集,但要注意其中的括號。例如:

define a 20;

#define b (a+10);

在c++中,雖然用巨集定義可以定義符號常量,但常用 const來定義符號常量。

例如: const double pl=3.1415926;與#define pi 3.145926;都是將識別符號pi定義為3.1415926,但是,這兩種又是有區別的。

不同點:

(1). 時期:#define是在編譯的預處理階段展開,而const是在 編譯、執行的時候起作用

(2). #define只是簡單的字串替換,沒有型別檢查。而const有對應的資料型別,是要進行判斷的,可以避免一些低階的錯誤

(3). 就儲存方式而言:define巨集在定義時不會分配記憶體,#define只是進行展開,有多少地方使用,就替換多少次,它定義的巨集常量在記憶體中有若干個備份;const常量在定義時會在記憶體中分配(可以是堆中也可以是棧中),const定義的唯讀變數在程式執行過程中只有乙份備份。

所以我們更推薦用const來來定義符號常量。

例如:#define max(a,b)a>b?a:b;如果在程式**現如下語句:

s=max(4,6);則被替換為:

s=4>6?4:6;

對於帶引數的巨集的展開,只是將語句中的巨集名後面括號內的實參字串代替#define命令列中的形參,例如上例用max(4,6),在展開時,4對應a,6對應b,替代巨集定義中的字串a>b?a:b,得到4>6?4:6如果有如下巨集定義:

#define sor(a) a*a;對於如下語句:是被指定 z=sqr(x+y);

這時,將以形參x+y代替a*a中a,成為:z=x+y*x+y;

需要注意的是,在x+y外面沒有括號,顯然這與設計者的原意不符,原意是希望得到:將被替換z=(x+y)*(x+y);

為了得到這個結果,應當在巨集定義時,在字串的形式引數外面加上乙個括號,避免歧義。即: #define sor(a) (a)*(a);

這樣再對z=sqr(x+y)進行巨集展開時,使用x+y代替(a)*(a)中a,就成為z=(x+y)*(x+y);的形式。

所謂「檔案包含」,是指將另乙個原始檔的全部內容包含到當前的原始檔中。在c++中,檔案包含命令的一般形式為:

#include《檔名》//或 #include"檔名」
檔名一般是以.h為副檔名,稱為「標頭檔案。檔案包含的這兩種格式區別在於:將檔名用<>括起來,用來包含那些由c++系統提供的並放在指定子目錄中的標頭檔案;而將檔名用雙引號括起來的,是用來包含使用者自己定義的放在應用程式當前目錄或其他目錄下的標頭檔案或其他原始檔。

檔案包含可以將標頭檔案中的內容直接引入,而不必再重複定義,減少了重複勞動,節省了程式設計時間。

在一般情況下,源程式中的所有語句都會參加編譯,但是有時候會希望根據一定的條件編譯原始檔的部分語句,這就是「條件編譯」。條件編譯使得同一源程式在不同的編譯條件下得到不同的目標**。

在c++中,常用的條件編譯命令有如下三種。

#ifdef 識別符號 

程式段1

#else

程式段2

#endif

該條件編譯命令的功能是:如果在程式中#define中定義了指定的「識別符號」時,就用程式段1參與編譯,否則,用程式段2參與編譯。

看個例子:

更改下**:

#ifndet 識別符號  

程式段1

#else

程式段2

#ebdif

該條件編譯命令的功能是:如果在程式中未定義指定的「識別符號」,就用程式段1參與編譯,否則,用程式段2參與編譯。

#if常量表示式1

程式段1

#elif常量表示式2

程式段2

.......

#elif常量表示式n

程式段n

#else程式段n+1

#endif

該條件編譯命令的功能是:依次計算常量表示式的值,當表示式的值為真時,則用相應的程式段參與編譯,如果全部表示式的值都為假,則用else後的程式段參與編譯。

【示例】

#include using namespace std;

#define k - 5

int main() {

#if k>0

cout

預處理預編譯(C )

一 預處理的由來 在c 的歷史發展中,有很多的語言特徵 特別是語言的晦澀之處 來自於c語言,預處理就是其中的乙個。c 從c語言那裡把c語言預處理器 被bjarne博士簡稱為cpp,不知道是不是c program preprocessor的簡稱 繼承過來。二 常見的預處理功能 預處理器的主要作用就是把...

C語言編譯預處理

title date br description c語言編譯預處理 2019 11 06 14 35 32 0800 預處理 c語言 c語言預處理是對源 進行初步轉換 碼農有道 c源程式 編譯預處理 編譯 優化程式 匯程式設計序 鏈結程式 可執行檔案其中編譯預處理階段,讀取c源程式,對其中的預處理...

編譯預處理

所謂編譯預處理,就是在c源程式的編譯之前,由編譯預處理程式對這些編譯預處理命令進行處理的過程。最常見的就是常量的替換。編譯預處理按功能可以分為巨集定義,檔案包含和條件編譯三類。編譯預處理命令以 開頭,下面進行詳細說明 一.巨集定義與符號常量 1.無參巨集定義 define 識別符號 字串 1 巨集名...