課(ke)程咨詢: 400-996-5531 / 投訴建議: 400-111-8989
認真做教育 專心促就業
預處(chu)(chu)理過程掃描源代碼,對其進(jin)行初步的轉(zhuan)換,產生新的源代碼提供給編(bian)譯器。可見預處(chu)(chu)理過程先于編(bian)譯器對源代碼進(jin)行處(chu)(chu)理。
在C 語言(yan)中,并沒有(you)任何內在的機制(zhi)來完成如下一些功能:在編(bian)譯時(shi)包(bao)含(han)其(qi)他源文件、定義宏、根據條件決定編(bian)譯時(shi)是否(fou)包(bao)含(han)某些代(dai)碼(ma)。要(yao)完成這(zhe)些工(gong)作,就需(xu)要(yao)使用預(yu)(yu)處理(li)(li)程序(xu)。盡管在目前絕大多(duo)(duo)數(shu)編(bian)譯器都包(bao)含(han)了預(yu)(yu)處理(li)(li)程序(xu),但通常認(ren)為它(ta)們(men)是獨立于(yu)編(bian)譯器的。預(yu)(yu)處理(li)(li)過(guo)程讀入源代(dai)碼(ma),檢查包(bao)含(han)預(yu)(yu)處理(li)(li)指(zhi)令的語句和(he)宏定義,并對源代(dai)碼(ma)進行響應的轉換(huan)。預(yu)(yu)處理(li)(li)過(guo)程還會刪(shan)除程序(xu)中的注釋(shi)和(he)多(duo)(duo)余的空白(bai)字(zi)符。
預處理指(zhi)(zhi)令是以(yi)#號開(kai)頭(tou)的(de)代碼(ma)(ma)行(xing)。#號必須(xu)是該行(xing)除了任(ren)何空白(bai)字(zi)符(fu)外(wai)的(de)第一(yi)個(ge)字(zi)符(fu)。#后是指(zhi)(zhi)令關鍵字(zi),在關鍵字(zi)和#號之間允許存(cun)在任(ren)意個(ge)數的(de)空白(bai)字(zi)符(fu)。整行(xing)語句構成了一(yi)條預處理指(zhi)(zhi)令,該指(zhi)(zhi)令將在編譯器進行(xing)編譯之前(qian)對源代碼(ma)(ma)做某些轉換。下面是部分預處理指(zhi)(zhi)令:
指令 用途
# 空指令,無任何效(xiao)果
#include 包含一個源代碼文件
#define 定義宏
#undef 取消已定義的(de)宏
#if 如果給定條件為真(zhen),則編譯下面代(dai)碼
#ifdef 如果宏已經(jing)定義,則(ze)編(bian)譯下面代碼
#ifndef 如果宏沒有定義,則編譯下面代碼
#elif 如果(guo)前面(mian)的#if給定條件不為(wei)真,當前條件為(wei)真,則編譯下面(mian)代碼
#endif 結束一個#if……#else條件(jian)編譯塊(kuai)
#error 停(ting)止編譯并顯示(shi)錯誤(wu)信(xin)息
一、文件包含
#include預(yu)處理指令的(de)作(zuo)用是(shi)在指令處展(zhan)開被(bei)(bei)包(bao)含的(de)文件(jian)。包(bao)含可以(yi)是(shi)多重的(de),也就是(shi)說一個被(bei)(bei)包(bao)含的(de)文件(jian)中還可以(yi)包(bao)含其(qi)他文件(jian)。標(biao)準C編譯器至少(shao)支持八重嵌套包(bao)含。
預處理過程不檢查在(zai)轉換單元中是否已經包(bao)含了某個(ge)文件(jian)并阻止對它的多次包(bao)含。這樣(yang)就可以在(zai)多次包(bao)含同(tong)(tong)一(yi)個(ge)頭文件(jian)時,通過給定編(bian)譯時的條件(jian)來(lai)達到不同(tong)(tong)的效(xiao)果。例如(ru):
#define AAA
#include "t.c"
#undef AAA
#include "t.c"
為了(le)避免那(nei)些只(zhi)能包含一次的頭文(wen)件(jian)被多次包含,可以(yi)在(zai)頭文(wen)件(jian)中用(yong)編譯時條(tiao)件(jian)來進行控制(zhi)。例如:
/*my.h*/
#ifndef MY_H
#define MY_H
……
#endif
在程序中包含頭文件有兩種格(ge)式:
#include
#include "my.h"
第一(yi)種(zhong)(zhong)方(fang)法是(shi)用(yong)尖括(kuo)號把(ba)頭(tou)(tou)(tou)文(wen)(wen)(wen)件(jian)括(kuo)起來(lai)(lai)。這種(zhong)(zhong)格(ge)式告(gao)訴預處(chu)理(li)程序在編譯器自(zi)帶(dai)的(de)或外(wai)部庫的(de)頭(tou)(tou)(tou)文(wen)(wen)(wen)件(jian)中搜(sou)索(suo)被(bei)包(bao)含(han)的(de)頭(tou)(tou)(tou)文(wen)(wen)(wen)件(jian)。第二種(zhong)(zhong)方(fang)法是(shi)用(yong)雙引號把(ba)頭(tou)(tou)(tou)文(wen)(wen)(wen)件(jian)括(kuo)起來(lai)(lai)。這種(zhong)(zhong)格(ge)式告(gao)訴預處(chu)理(li)程序在當(dang)前被(bei)編譯的(de)應用(yong)程序的(de)源代碼文(wen)(wen)(wen)件(jian)中搜(sou)索(suo)被(bei)包(bao)含(han)的(de)頭(tou)(tou)(tou)文(wen)(wen)(wen)件(jian),如果(guo)找不(bu)到,再搜(sou)索(suo)編譯器自(zi)帶(dai)的(de)頭(tou)(tou)(tou)文(wen)(wen)(wen)件(jian)。
采(cai)用(yong)兩種不同(tong)(tong)包(bao)含格式的(de)理(li)由在(zai)(zai)于,編(bian)譯(yi)器(qi)是安裝在(zai)(zai)公(gong)共子(zi)目錄下(xia)的(de),而被編(bian)譯(yi)的(de)應用(yong)程序(xu)是在(zai)(zai)它們(men)自己的(de)私有子(zi)目錄下(xia)的(de)。一(yi)個應用(yong)程序(xu)既包(bao)含編(bian)譯(yi)器(qi)提供的(de)公(gong)共頭(tou)(tou)(tou)文件(jian),也包(bao)含自定義的(de)私有頭(tou)(tou)(tou)文件(jian)。采(cai)用(yong)兩種不同(tong)(tong)的(de)包(bao)含格式使得編(bian)譯(yi)器(qi)能(neng)夠在(zai)(zai)很多頭(tou)(tou)(tou)文件(jian)中區別出一(yi)組公(gong)共的(de)頭(tou)(tou)(tou)文件(jian)。
二、宏
宏(hong)(hong)(hong)(hong)定(ding)義(yi)了一個(ge)代(dai)表特定(ding)內容的(de)(de)(de)(de)標識符。預處(chu)理過程(cheng)會把源代(dai)碼中出現的(de)(de)(de)(de)宏(hong)(hong)(hong)(hong)標識符替換成宏(hong)(hong)(hong)(hong)定(ding)義(yi)時(shi)的(de)(de)(de)(de)值。宏(hong)(hong)(hong)(hong)最(zui)常見的(de)(de)(de)(de)用(yong)(yong)(yong)法是(shi)定(ding)義(yi)代(dai)表某個(ge)值的(de)(de)(de)(de)全(quan)局符號。宏(hong)(hong)(hong)(hong)的(de)(de)(de)(de)第(di)二種用(yong)(yong)(yong)法是(shi)定(ding)義(yi)帶參數的(de)(de)(de)(de)宏(hong)(hong)(hong)(hong),這樣的(de)(de)(de)(de)宏(hong)(hong)(hong)(hong)可以象函數一樣被調用(yong)(yong)(yong),但它是(shi)在調用(yong)(yong)(yong)語句處(chu)展(zhan)開宏(hong)(hong)(hong)(hong),并用(yong)(yong)(yong)調用(yong)(yong)(yong)時(shi)的(de)(de)(de)(de)實際參數來代(dai)替定(ding)義(yi)中的(de)(de)(de)(de)形式參數。
1.#define指令
#define預處理指令是用來(lai)定義宏的(de)。該(gai)指令最簡單的(de)格式是:首(shou)先神明一(yi)個(ge)標識(shi)符(fu),然后給出(chu)這(zhe)個(ge)標識(shi)符(fu)代(dai)(dai)表的(de)代(dai)(dai)碼(ma)。在后面的(de)源代(dai)(dai)碼(ma)中,就用這(zhe)些(xie)代(dai)(dai)碼(ma)來(lai)替(ti)代(dai)(dai)該(gai)標識(shi)符(fu)。這(zhe)種宏把程序中要用到的(de)一(yi)些(xie)全(quan)局值(zhi)提取出(chu)來(lai),賦(fu)給一(yi)些(xie)記憶標識(shi)符(fu)。
#define MAX_NUM 10
int array[MAX_NUM];
for(i=0;i
在(zai)這(zhe)個例子中,對于閱讀該程序(xu)的(de)(de)(de)人(ren)來(lai)(lai)說,符(fu)(fu)號MAX_NUM就(jiu)有特定(ding)的(de)(de)(de)含(han)義(yi),它代表的(de)(de)(de)值給出(chu)了(le)數組(zu)所能(neng)容納的(de)(de)(de)最大元素數目(mu)。程序(xu)中可以(yi)多次使用這(zhe)個值。作(zuo)為一種(zhong)約定(ding),習慣上總(zong)是全(quan)部用大寫字母(mu)來(lai)(lai)定(ding)義(yi)宏,這(zhe)樣易(yi)于把程序(xu)紅(hong)的(de)(de)(de)宏標識(shi)符(fu)(fu)和一般變量標識(shi)符(fu)(fu)區別開來(lai)(lai)。如果想要改變數組(zu)的(de)(de)(de)大小,只需(xu)要更改宏定(ding)義(yi)并重新(xin)編譯程序(xu)即可。
宏(hong)(hong)表示的(de)值可以是(shi)一(yi)個常量表達(da)式,其中允許包括(kuo)前面(mian)已經定(ding)義的(de)宏(hong)(hong)標識符。例如:
#define ONE 1
#define TWO 2
#define THREE (ONE+TWO)
注(zhu)意上(shang)面的宏(hong)定(ding)義使用了括(kuo)(kuo)號。盡管它(ta)們并(bing)不是必須的。但出于謹慎考(kao)慮,還是應該(gai)加上(shang)括(kuo)(kuo)號的。例如:
six=THREE*TWO;
預處理過(guo)程把上(shang)面的一行代碼轉換成:
six=(ONE+TWO)*TWO;
如(ru)果(guo)沒有(you)那個括(kuo)號,就轉換成six=ONE+TWO*TWO;了。
宏還可(ke)以代(dai)表一個字(zi)符串常量(liang),例如:
#define VERSION "Version 1.0 Copyright(c) 2003"
2.帶參數(shu)的#define指令
帶參數的宏(hong)和函數調用看起(qi)來有(you)些相似。看一(yi)個例子:
#define Cube(x) (x)*(x)*(x)
可以時任何(he)數(shu)(shu)字表(biao)達式(shi)甚至函(han)數(shu)(shu)調用來代替(ti)參數(shu)(shu)x.這里再次提醒大家注意括(kuo)號(hao)的使用。宏展開(kai)后完(wan)全包(bao)含在一對括(kuo)號(hao)中(zhong),而且(qie)參數(shu)(shu)也(ye)包(bao)含在括(kuo)號(hao)中(zhong),這樣就保證了宏和參數(shu)(shu)的完(wan)整(zheng)性。看一個用法:
int num=8+2;
volume=Cube(num);
展開后為(8+2)*(8+2)*(8+2);
如果沒有那些括號就變為8+2*8+2*8+2了。
下面(mian)的用法是不安全(quan)的:
volume=Cube(num++);
如果Cube是一個(ge)函數,上面(mian)的寫法(fa)是可(ke)以理解的。但是,因為Cube是一個(ge)宏,所以會產生(sheng)(sheng)副作用(yong)。這里(li)的擦書不(bu)是簡單的表達(da)式(shi),它們將產生(sheng)(sheng)意想不(bu)到(dao)的結果。它們展開后是這樣的:
volume=(num++)*(num++)*(num++);
很顯然,結果是10*11*12,而不是10*10*10;
那(nei)么怎樣(yang)安全的使用Cube宏呢(ni)?必(bi)須把可能(neng)產生副作(zuo)用的操作(zuo)移到(dao)宏調(diao)用的外(wai)面進行(xing):
int num=8+2;
volume=Cube(num);
num++;
【免責(ze)聲明】本文(wen)部(bu)分系(xi)轉(zhuan)載,轉(zhuan)載目的在于傳遞(di)更多(duo)信(xin)息,并不(bu)代表本網贊同(tong)其(qi)觀(guan)點和(he)對(dui)其(qi)真(zhen)實性負責(ze)。如涉及作品(pin)內容、版權(quan)和(he)其(qi)它問題,請在30日內與聯(lian)系(xi)我(wo)們,我(wo)們會(hui)予(yu)以更改或刪除相(xiang)關文(wen)章(zhang),以保證您的權(quan)益!