預處理命令知識點

2021-09-10 13:47:22 字數 3011 閱讀 5994

ansi c標準規定,可以在c源程式中加入一些「預處理命令」,以改進程式設計環節,提高程式設計效率。這些預處理命令是由ansi c統一規定的,但是它不是c語言本身的組成部分,不能直接對它們進行編譯(因為編譯程式不能識別它們)。必須在對程式進行通常的編譯之前 ,先對程式中這些特殊的命令進行「預處理」,即根據預處理命令對程式作相應的處理。

經過預處理後的程式不再包含預處理命令了,最後再由編譯程式對預處理後的源程式進行通常的編譯處理,得到可供執行的目標**。

預處理命令不是c語言的一部分。

c提供的預處理功能主要有三種:巨集定義、檔案包含、條件編譯

#define  標識(shi)符  字串

#define  pi  3.1415926

這個識別符號(名字)稱為「巨集名」,在預編譯時將巨集名替換成字串的過程稱為「巨集展開」,#define是巨集定義命令。

(1)巨集名一般習慣用大寫字母

(2)使用巨集名代替乙個字串,可以減少程式中重複書寫某些字串的工作量

eg. 定義陣列大小 ,可以

#define array_szie   1000

int array[array_size];

(3)巨集定義不是c語句,不必在行末加分號

(4)在進行巨集定義時,可以引用已經定義的巨集名,可以層層置換

#define r 3.0

#defiine pi 3.1415926

#define l  2*pi*r

(5)巨集定義是專門用於預處理命令的乙個專用名詞,它與定義變數的含義不同,只作字元替換,不分配記憶體空間。

(6)對程式中用雙撇號括起來的字串內的字元,即使與巨集名相同,也不進行置換。

#define  巨集名(參數列)   字串

#define  s(a,b)     a*b                 #define  s(a,b)    (a)*(b)

#define  s(r)      pi*r*r                 #define  s(r)      pi*(r)*(r)

帶引數的巨集定義和函式是不同的。主要有:

1.函式呼叫時,先求出實參表示式的值,然後帶入形參。

而使用帶引數的巨集只是進行簡單的字元替換。

2.函式呼叫是在程式執行時處理的,為形參分配臨時的記憶體單元。

而紅展開則是在編譯前進行的,在展開時並不分配記憶體單元,不進行值得傳遞處理。

3.對函式中的實參和形參都要定義型別,二者的型別要求一致,如不一致,應進行型別轉換。

而巨集不存在型別問題,巨集名無型別,只是乙個符號代表,展開時代入指定的字串即可。

4.呼叫函式只可得到乙個返回值。

而用巨集可以設法得到幾個結果。

#define  circle(r,l,s,v)   l=2*pi*r;s=pi*r*r;v=4.0/3/0*pi*r*r*r

5.使用巨集次數多時,巨集展開後源程式變長,因為每展開一次都使程式增長。

而函式呼叫不會使源程式變長。

6.巨集替換不佔執行時間,只佔編譯時間。

而函式呼叫則佔執行時間(分配單元、保留現場、值傳遞、返回)。

#define  max(x,y)   (x)>(y)?(x):(y)

所謂「檔案包含」處理是指乙個原始檔可以將另外乙個原始檔的全部內容包含進來,即將另外的檔案包含到本檔案之中。

c語言提供了#include命令用來實現「檔案包含」的操作。其一般形式為#include "檔名"  或 #include《檔名》

注意:在編譯時並不是對兩個檔案分別進行編譯,然後再將它們的目標程式連線的,而是在經過編譯預處理後將標頭檔案(.h)包含到主檔案中,得到乙個新的源程式,然後對這個檔案進行編譯,得到乙個目標(.obj)檔案。被包含的檔案成為新的原始檔的一部分,而單獨生成目標檔案。(個人感覺最後一句話有問題)

在#include命令中,檔名可以用雙撇號或尖括號括起來。二者的區別是:

用尖括號時,系統到存放c庫函式標頭檔案的目錄中查詢要包含的檔案,這稱為標準方式。

用雙撇號時,系統先在使用者當前目錄中尋找要包含的檔案,若找不到,再按標準方式查詢。

一般來說,如果為呼叫庫函式而用#include命令來包含相關的標頭檔案,則用尖括號,以節省查詢時間。

如果要包含的是使用者自己編寫的檔案(這種檔案一般都在使用者當前目錄中),一般用雙撇號。

一般情況下,源程式中所有行都參加編譯。但是有時候希望程式中一部分內容只在滿足一定條件時才進行編譯,也就是對這一部分內容指定編譯的條件,這就是「條件編譯」。

條件編譯命令的幾種形式:

1.它的作用是:若指定的識別符號已經被#define命令定義過,則在程式編譯階段編譯程式段1;否則編譯程式段2。其中#else部分可以沒有。

#ifdef 識別符號

程式段1

#else

程式段2

#endif

#ifdef 識別符號

程式段1

#endif

2.它的作用是:若指定的識別符號未被#define命令定義過,則在程式編譯階段編譯程式段1;否則編譯程式段2。其中#else部分可以沒有。

#ifndef 識別符號

程式段1

#else

程式段2

#endif

#ifndef 識別符號

程式段1

#endif

3.它的作用是:當指定的表示式值為真(非零)時就編譯程式段1;否則編譯程式段2。可以事先給定條件,使程式在不同條件下執行不同的功能。

#if  表示式

程式段1

#else

程式段2

#endif

#if  表示式

程式段1

#endif

編譯和預處理相關知識點

本質 翻譯官,把高階語言翻譯成機器指令 常用選項 gcc o 輸出檔名 輸入檔名 gcc o build 01.c 字尾不能為其他 gcc v o build 01.c gcc l o 用來指定程式要鏈結的庫,l引數緊接著就是庫名 gcc l o l引數跟著的是庫檔案所在的目錄名 gcc e ogc...

C 預處理相關知識點總結

c提供的預處理命令有3種 1 巨集定義 2 檔案包含 3 條件編譯 預處理命令不是c語句,為了與一般的c語句相區別,這些命令都是以 開頭的。c原始檔經過預處理之後,不再含有任何預處理命令。單個.c原始檔轉換為可執行檔案需要經過4個步驟 1 預處理 2 編譯 3 彙編 4 鏈結 多個.c原始檔轉換為可...

文字預處理等知識點打卡

一 文字預處理 1.讀入文字 re.sub pattern,repl,string,count 0,flags 0 pattern 表示正規表示式中的模式字串 repl 被替換的字串 既可以是字串,也可以是函式 string 要被處理的,要被替換的字串 count 匹配的次數,預設是全部替換 fla...