版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
2024/12/23第7章編譯預(yù)處理C/C++語(yǔ)言程序設(shè)計(jì)案例教程7.1宏定義7.2文件包含7.3條件編譯2024/12/232預(yù)處理不是C語(yǔ)言本身的組成部分,不能直接進(jìn)行編譯。在對(duì)源程序編譯之前,系統(tǒng)先將這部分命令進(jìn)行“預(yù)處理”,處理后源程序?qū)⒉辉侔A(yù)處理命令,隨后系統(tǒng)完成編譯,鏈接生成目標(biāo)程序。C語(yǔ)言提供3種預(yù)處理功能:宏定義;文件包含;條件編譯。2024/12/233案例一宏的使用1.問題描述計(jì)算物體在水中的浮力以及在不同液體和不同物體體積下受到的浮力(假設(shè)物體全部沉入水中)。2.問題分析浮力=pgv。在水中,物體受到的浮力與體積有關(guān),g是常數(shù),將g定義為宏(無(wú)參宏)。在液體中,不同物體在不同液體中受到的浮力與物體體積和液體的密度有關(guān),將計(jì)算公式也定義為宏(有參宏)。2024/12/2343.?C語(yǔ)言代碼#include"stdio.h"/*預(yù)處理指令是以#號(hào)為開頭的代碼行,#include是一個(gè)文件包含預(yù)處理*/#defineg9.8/*g定義為無(wú)參宏*/#defineF(p,v)(p*9.8*v)/*將浮力計(jì)算公式定義為有參宏,物體體積v和液體密度p為參數(shù),也可將F(p,v)定義為(p*g*v),即有參宏的嵌套定義*/voidmain(){floatF1,F2;floatp,v;/*以下部分計(jì)算物體在水中的浮力F1*/printf("請(qǐng)輸入在水中物體的體積v\n");scanf("%f",&v);F1=1000*g*v;/*替換無(wú)參宏名g,將g替換成數(shù)值9.8*/printf("物體在水中的浮力是F1=%f\n",F1);/*以下部分計(jì)算不同物體在不同液體中的浮力F2*/printf("請(qǐng)輸入在某液體中液體的密度p和物體的體積v\n");scanf("%f,%f",&p,&v);F2=F(p,v); /*替換有參宏F(p,v),將F(p,v)替換為表達(dá)式p*9.8*v*//*如果采用宏的嵌套定義,F(xiàn)(p,v)首先替換為表達(dá)式p*g*v,再替換為p*9.8*v*/printf("物體在液體中的浮力F2=%f\n",F2);#undefg; /*取消g宏定義*/#undefF(p,v); /*取消宏F(p,v)定義*/}2024/12/2354.程序運(yùn)行結(jié)果請(qǐng)輸入在水中物體的體積v12.2物體在水中的浮力是F1=119560請(qǐng)輸入在某液體中液體的密度p和物體的體積v700,24物體在液體中的浮力F2=1646402024/12/2367.1宏定義
宏定義是預(yù)處理命令中的一種,它提供了一種可以替換源代碼中字符串的機(jī)制。根據(jù)宏中是否有參數(shù),可以將宏定義分為不帶參數(shù)的宏定義和帶參數(shù)的宏定義。2024/12/237宏定義是預(yù)處理命令中的一種,它提供了一種可以替換源代碼中字符串的機(jī)制。根據(jù)宏中是否有參數(shù),可以將宏定義分為不帶參數(shù)的宏定義和帶參數(shù)的宏定義。2024/12/2387.1.1不帶參數(shù)的宏定義
不帶參數(shù)的宏定義格式如下:#define標(biāo)識(shí)符字符串宏定義格式中“標(biāo)識(shí)符”為用戶定義標(biāo)識(shí)符,稱為宏名,也叫符號(hào)常量,一般用大寫字母表示。字符串可以是常量、表達(dá)式、格式串等。注意:宏定義不是C語(yǔ)言的語(yǔ)句,宏定義結(jié)尾沒有分號(hào)。2024/12/239說(shuō)明:(1)預(yù)處理中,源程序在宏定義之后出現(xiàn)的所有與宏名一樣的標(biāo)識(shí)符都替換成宏定義中的字符串,不做語(yǔ)法檢查。例如:將#defineg9.8錯(cuò)誤地寫成#defineg98,則在編譯預(yù)處理中將g替換為98進(jìn)行編譯。(2)源程序中宏可以嵌套定義。例如,計(jì)算圓柱體體積:#defineR6.3#defineHIGHT12.5#defineVOLUME(3.14*R*R*HIGHT)/*宏的嵌套定義*/在?#defineVOLUME(3.14*R*R*HIGHT)中HIGHT和R宏定義VOLUME在之前,即為宏嵌套定義。2024/12/2310嵌套定義的替換過(guò)程為由外到內(nèi),例如:①將宏名R進(jìn)行替換,替換結(jié)果為#defineVOLUME(3.14*6.3*6.3*HIGHT)②將宏名HIGHT進(jìn)行替換,替換結(jié)果為#defineVILUME(3.14*6.3*6.3*12.5)案例一中:#defineg9.8 /*g定義為無(wú)參宏*/#defineF(p,v)(p*g*v) /*g宏定義在F之前,也是宏的嵌套定義*/(3)宏定義的作用域。一個(gè)宏名與變量一樣也有它的作用域,宏名的作用范圍從該宏名的宏定義處開始到所在文件的結(jié)尾,或用#undef命令取消該宏定義為止。例如,在如下程序段計(jì)算物體在水中的浮力,#include"stdio.h"#defineg9.8 /*宏名g定義開始*/voidmain(){floatF1;floatp,v;...printf("F1=%f\n",F1);undefg; /*undef使得g的宏定義的作用范圍到此處為止*/#defineg9.78 /*宏名g重新定義新的精度*/
…}2024/12/23117.1.2帶參數(shù)的宏定義
帶參數(shù)的宏定義格式如下:#define宏名(參數(shù)表)字符串宏名一般為大寫,參數(shù)表可以有一個(gè)或多個(gè)參數(shù)組成,參數(shù)之間用逗號(hào)分隔。例如案例一中,#defineF(p,v)(p*9.8*v),p和v為參數(shù)。帶參數(shù)宏的調(diào)用格式如下:宏名(實(shí)參表)即將實(shí)參替換形參,其他部分不變。例如,假設(shè)有#defineSW(x)(x)*(x)如果程序中有語(yǔ)句x=SW(5);,那么編譯系統(tǒng)會(huì)將SW(5)替換為5*5。但輸出語(yǔ)句雙引號(hào)中的宏定義不做替換。例如:#defineXYZthisisatestprintf("XYZ");輸出XYZ,而不是thisisatest。2024/12/2312說(shuō)明:(1)定義時(shí)參數(shù)和字符串部分要分別用括號(hào)括起來(lái),宏名與參數(shù)表的括號(hào)之間不要加空格,否則就成為不帶參數(shù)的宏定義語(yǔ)句了。(2)為了保證在宏展開后,字符串中各個(gè)參數(shù)的計(jì)算順序正確,應(yīng)當(dāng)在宏定義中的字符串最外面以及其中的各個(gè)參數(shù)外面加上圓括號(hào)。例如,比較以下兩個(gè)例子。①#definesqr(x)(x*x)②#definesqr(x)((x)*(x))如果在后續(xù)程序中有s=sqr(a+b),程序在預(yù)處理時(shí)會(huì)產(chǎn)生不同的結(jié)果:①sqr(x)替換為(a+b*a+b);②sqr(x)替換為(a+b)*(a+b)。(3)在帶參宏定義時(shí),也有宏嵌套定義。(4)帶參數(shù)的宏和函數(shù)存在相似之處。例如它們的表示形式都是由一個(gè)名字加上幾個(gè)參數(shù),引用方式也相同,實(shí)參和形參的個(gè)數(shù)都要求相同,但是要注意它們之間的區(qū)別。比較以下有參宏和函數(shù)的定義:2024/12/2313例7.1將一表達(dá)式分別定義為宏和函數(shù)。#include<stdio.h>#defineSQR(x)((x)*(x))/*宏定義以"#define"開頭,不需要對(duì)形參進(jìn)行數(shù)據(jù)類型聲明,不需對(duì)宏進(jìn)行宏類型聲明,在宏展開時(shí)只是完成替換。*/intSR(intx)/*函數(shù)定義沒有"#define",有參函數(shù)需要對(duì)形參進(jìn)行數(shù)據(jù)類型聲明,函數(shù)調(diào)用時(shí)需要參數(shù)傳遞,要聲明函數(shù)的類型(int類型除外)。*/{return((x)*(x));}voidmain(){inti;i=1;printf("宏替換如下:\n");do{printf("%d\n",SQR(i++));/*宏替換*/}while(i<=5);i=1;printf("函數(shù)運(yùn)行如下:\n");do{printf("%d\n",SR(i++));/*函數(shù)調(diào)用*/}while(i<=5);}2024/12/2314程序運(yùn)行結(jié)果如下:宏替換如下:1925函數(shù)運(yùn)行如下12/2315除以上幾點(diǎn)外,有參宏與函數(shù)不同還有:(1)代碼長(zhǎng)度。每次使用時(shí),宏定義代碼都被插入程序中,程序的長(zhǎng)度將增長(zhǎng)。函數(shù)定義代碼只出現(xiàn)于一個(gè)地方;每次使用這個(gè)函數(shù)時(shí),都被調(diào)用那個(gè)地方的同一份代碼。(2)運(yùn)算速度。宏替換只占編譯時(shí)間,不占用運(yùn)行時(shí)間。函數(shù)由于在函數(shù)調(diào)用開始和返回時(shí)要進(jìn)行相應(yīng)的處理,因此要占用一些運(yùn)行時(shí)間。(3)處理時(shí)間不同。宏展開是在編譯預(yù)處理時(shí)進(jìn)行的。函數(shù)調(diào)用是在程序運(yùn)行時(shí)處理的,并且要為函數(shù)分配內(nèi)存空間。(4)參數(shù)求值。帶參數(shù)的宏是將形參用實(shí)參來(lái)代替,即簡(jiǎn)單的字符替換。宏展開時(shí)都將重新求值。函數(shù)調(diào)用時(shí),要先計(jì)算出實(shí)參表達(dá)式的值,然后將此值傳給形參;參數(shù)在函數(shù)調(diào)用時(shí)只求值一次。由于有參宏對(duì)參數(shù)沒有數(shù)據(jù)類型的約定,在某些情況下,使用有參宏定義會(huì)更方便:①有如下宏定義:#defineMAX1(a,b)((a>b)?a:b)/*a、b的數(shù)據(jù)類型可以是整型、浮點(diǎn)型*/②有如下函數(shù)定義:MAX2(inta,intb){return((a>b)?a:b);}/*a、b如果是浮點(diǎn)型,需修改形參的數(shù)據(jù)類型定義*/2024/12/2316案例二文件包含的使用1.問題描述根據(jù)物體的體積和液體密度,計(jì)算物體的浮力(假設(shè)物體全部沉入水中)。2.問題分析使用文件包含預(yù)處理,將#defineg9.8和#defineF(p,v)(p*g*v)保存在user.h文件,源程序中不再出現(xiàn)宏定義。2024/12/23173.?C語(yǔ)言代碼#include<stdio.h>#include"user.h"/*使用#include將宏定義所在文件加載到C源程序中*/main(){floatp,v,F2;printf("請(qǐng)輸入在某液體中液體的密度p和物體的體積v\n");scanf("%f,%f",&p,&v);F2=F(p,v);printf("物體在液體中的最大浮力F2=%f\n",F2);}4.程序運(yùn)行結(jié)果請(qǐng)輸入在某液體中液體的密度p和物體的體積v700,15物體在液體中的最大浮力F2=1029002024/12/23187.2文件包含
文件包含的使用是編寫C語(yǔ)言程序中不可缺少的,我們?cè)谝肅語(yǔ)言庫(kù)函數(shù)時(shí)要使用它;另外,我們也可以將平時(shí)積累的一些有用的自定義函數(shù)做成一個(gè)自定義函數(shù)庫(kù)文件,要使用它們時(shí)只需采用文件包含將它們引用過(guò)來(lái)使用就行,這樣就減少了編程的工作量,提高編譯效率。文件包含定義格式如下:#include<文件名>或#include"文件名"2024/12/2319例如:#include<stdio.h>或#include"stdio.h"。一個(gè)文件包含預(yù)處理只能包含一個(gè)被包含文件。例如,使用文件包含計(jì)算一個(gè)實(shí)數(shù)的絕對(duì)值和的sin()值,并輸出。輸入輸出函數(shù)在stdio.h文件中,絕對(duì)值和sin()在math.h文件中,所以除了要在文件包含預(yù)處理中有stdio.h,還需要有math.h。#include<stdio.h>/*包含標(biāo)準(zhǔn)輸入輸出的頭文件stdio.h*/#include<math.h>/*包含數(shù)學(xué)函數(shù)的頭文件math.h*/main(){...}2024/12/2320除包含系統(tǒng)文件外,也可將用戶定義的宏保存在用戶文件中,在源程序需要宏的時(shí)候,將用戶文件包含在源文件中。如案例二中,將宏定義g和F定義于user.h文件中。使用文件包含,需注意以下幾點(diǎn):(1)若使用符號(hào)<?>,系統(tǒng)到存放C庫(kù)函數(shù)頭文件所在目錄尋找要包含的文件,一般使用庫(kù)函數(shù)使用此符號(hào);若使用符號(hào)"",系統(tǒng)在用戶程序所在的當(dāng)前目錄尋找要包含的文件,如果找不到再到C庫(kù)函數(shù)頭文件所在目錄尋找,一般使用用戶函數(shù)使用此符號(hào)。(2)在預(yù)處理時(shí),文件包含命令用被包含文件內(nèi)容替換,成為源文件內(nèi)容的一部分,與其他源文件代碼一起參加編譯。例如案例二中使用#include將stdio.h的所有內(nèi)容,與user.h包含宏定義的文件內(nèi)容嵌入到該預(yù)處理命令處成為源文件的一部分。(3)可以將多個(gè)需要包含的內(nèi)容寫到一個(gè)頭文件中,如案例二;也可以將文件進(jìn)行嵌套包含。2024/12/2321例7.2文件嵌套包含的使用。將?#defineF(p,v)(p*g*v)宏定義保存在user1.h中,#defineg9.8宏定義保存在user2.h中。user1.h文件內(nèi)容:#include"user2.h"#defineF(p,v)(p*g*v)user2.h文件內(nèi)容:#defineg9.8/*注意:這里沒有文件包含預(yù)處理*/使用文件嵌套預(yù)處理之后,案例二中的文件預(yù)處理程序段如下所示:#include"stdio.h"#include"user1.h"/*使用文件包含,將宏定義的g和F進(jìn)行預(yù)處理*/main(){floatp,v,F2;printf("請(qǐng)輸入在某液體中液體的密度p和物體的體積v\n");scanf("%f,%f",&p,&v);F2=F(p,v);printf("theF2is%f\n",F2);}2024/12/2322程序運(yùn)行結(jié)果如下:請(qǐng)輸入在某液體中液體的密度p和物體的體積v700,24theF2=164640這與案例二中計(jì)算在某液體中物體受到的浮力結(jié)果相同。2024/12/2323案例三#ifdef命令和#ifndef命令的使用1.問題描述編寫程序,使程序編譯后的程序既能夠在16位機(jī)上運(yùn)行的目標(biāo)代碼,也能在32位機(jī)上運(yùn)行的目標(biāo)代碼。2.問題分析16位機(jī)與32位機(jī)在數(shù)據(jù)類型上主要是整數(shù)存儲(chǔ)長(zhǎng)度不一樣,采用條件編譯解決數(shù)據(jù)位數(shù)的問題。2024/12/23243.?C語(yǔ)言代碼#include<stdio.h>main(){#ifdefPC16/*若PC16被定義為宏,則完成以下預(yù)處理*/#defineINTSIZE16/*?16位整型被定義為宏INTSIZE*/#else/*若PC16未被定義為宏,則完成以下預(yù)處理*/#defineINTSIZE32/*32位整型數(shù)被定義為宏INTSIZE*/#endif/*#ifdef結(jié)束*/}2024/12/23257.3條件編譯
為了測(cè)試程序運(yùn)行情況,可以通過(guò)在程序中添加一些輸出語(yǔ)句,根據(jù)輸出的結(jié)果判定程序運(yùn)行結(jié)果是否正確,對(duì)錯(cuò)誤的程序進(jìn)行修改直到滿足需要。調(diào)試結(jié)束后將這些輸出語(yǔ)句再進(jìn)行刪除。C語(yǔ)言提供了條件編譯預(yù)處理,能更好的解決測(cè)試問題。對(duì)程序中的所有源代碼有時(shí)只需要對(duì)其中部分代碼進(jìn)行編譯,也就是對(duì)部分代碼有選擇地進(jìn)行編譯,該過(guò)程稱為條件編譯。條件編譯主要有#ifdef命令、#ifndef命令還有#if命令。條件編譯主要有以下幾種形式,#ifdef和#ifnde,以及#if,分別如表7-1~7-3所示2024/12/2326表7-1#ifdef條件編譯形式條件編譯形式說(shuō)明#ifdef宏名語(yǔ)句
#endif如果宏名被定義過(guò),則執(zhí)行語(yǔ)句#ifdef宏名語(yǔ)句1#else
語(yǔ)句2#endif宏名如果宏名被定義過(guò),則執(zhí)行語(yǔ)句1,否則執(zhí)行語(yǔ)句22024/12/2327表7-2#ifndef條件編譯形式條件編譯形式說(shuō)明#ifndef宏名語(yǔ)句
#endif如果宏名未被定義過(guò),則執(zhí)行語(yǔ)句#ifndef宏名語(yǔ)句1#else
語(yǔ)句2#endif如果宏名未被定義過(guò),則執(zhí)行語(yǔ)句1,否則執(zhí)行語(yǔ)句22024/12/2328表7-3#if條件編譯形式條件編譯形式說(shuō)明#if表達(dá)式1
程序段1#endif如果表達(dá)式1為真,則執(zhí)行程序段1#if表達(dá)式1程序段1#else程序段2#endif如果表達(dá)式1為真,則執(zhí)行程序段1,否則執(zhí)行程序段2#if表達(dá)式1程序段1#elif表達(dá)式2程序段2#endif如果表達(dá)式1為真,則執(zhí)行程序段1,否則表達(dá)式2為真,執(zhí)行程序段22024/12/2329(1)?#if命令中表達(dá)式必須是常數(shù)表達(dá)式,不能包含變量,因?yàn)闂l件編譯在編譯預(yù)處理時(shí)進(jìn)行,而在預(yù)處理時(shí)不可能知道變量的值。(2)?#if和#elif常常與defined命令配合使用,defined命令的格式為defined(宏名)或defined宏名功能:判斷某個(gè)宏是否已經(jīng)定義,如果已經(jīng)定義,defined命令返回1,否則返回0。defined命令只能與#if或#elif配合使用,不能單獨(dú)使用。例如,#ifdefined(USA)的含義是“如果定義了宏USA”。2024/12/2330例7.3#if命令的使用:根據(jù)需求計(jì)算3個(gè)數(shù)中最大值或最小值。#include<stdio.h>#defineMAX1voidmain(){inta,b,c,max,min;printf("input3numbers:");
scanf("%d%d%d",&a,&b,&c);#ifMAX/*定義的宏為真(或非0)則完成以下程序段;也可寫為#ifdefine*/
{max=a; if(b>max)max=b; if(c>max)max=c;printf("themax=%d\n",max);}#else{min=a; if(b<min)min=b; if(c<min)min=c;printf("themin=%d\n",min);}#endif}2024/12/2331程序運(yùn)行結(jié)果如下:input3numbers:347421themax=74說(shuō)明:(1)當(dāng)程序調(diào)試完成后,使編譯條件改變?yōu)椴粷M足調(diào)試條件,原來(lái)添加的輸出信息就不參與編譯,相當(dāng)于被刪除了。(2)?#if語(yǔ)句可以減少目標(biāo)代碼的長(zhǎng)度,而使用if語(yǔ)句將對(duì)整個(gè)程序進(jìn)行編譯,所以目標(biāo)程序會(huì)比較長(zhǎng)。2024/12/2332本章小結(jié)本章介紹了宏定義、文件包含和條件編譯三種編譯預(yù)處理。編譯預(yù)處理是C語(yǔ)言的一大特色,也是C語(yǔ)言與其他高級(jí)語(yǔ)言的重要區(qū)別之一。編譯預(yù)處理與源程序編譯不同,編譯預(yù)處理是在編譯之前對(duì)預(yù)處理指令先進(jìn)行處理。常用的預(yù)處理語(yǔ)句主要有宏、文件包含和條件編譯。宏定義時(shí)用一個(gè)標(biāo)識(shí)符來(lái)表示一個(gè)常量或表達(dá)式,在宏調(diào)用中將標(biāo)識(shí)符替換成常量或表達(dá)式。宏增加編譯的時(shí)間,但不增加程序運(yùn)行的時(shí)間。文件包含可以將多個(gè)源文件連接成一個(gè)源文件一起進(jìn)行編譯,并生成一個(gè)目標(biāo)文件。條件編譯可根據(jù)設(shè)定條件來(lái)實(shí)現(xiàn)對(duì)源程序中的某一部分進(jìn)行編譯,合理的使用編譯預(yù)處理將使得程序更具有移植性和靈活性。使用預(yù)處理功能便于程序的修改、閱讀、移植和調(diào)試,也便于實(shí)現(xiàn)模塊化程序設(shè)計(jì)。2024/12/2333預(yù)處理命令
學(xué)習(xí)的意義
C語(yǔ)言的一個(gè)重要特征是它的預(yù)處理功能。我們知道,一個(gè)高級(jí)語(yǔ)言源程序在計(jì)算機(jī)上運(yùn)行,必須先用編譯程序?qū)⑵浞g為機(jī)器語(yǔ)言。編譯包括詞法分析、語(yǔ)法分析、代碼生成、代碼優(yōu)化等步驟,有時(shí)在編譯之前還要做某些預(yù)處理工作,如去掉注釋,變換格式等。C語(yǔ)言允許在源程序中包含預(yù)處理命令,在正式編譯之前(詞法分析之前)系統(tǒng)先對(duì)這些命令進(jìn)行“預(yù)處理”,然后整個(gè)源程序再進(jìn)行通常的編譯處理。從語(yǔ)法上講,這些預(yù)處理命令不是C語(yǔ)言的一部分,但使用它們卻擴(kuò)展了C語(yǔ)言程序設(shè)計(jì)的環(huán)境,可以簡(jiǎn)化程序開發(fā)過(guò)程,提高程序的可讀性,也更有利于移植和調(diào)試C語(yǔ)言程序。本章主要介紹宏定義、文件包括和條件編譯等預(yù)處理命令。2024/12/2334學(xué)習(xí)的意義
源程序生成執(zhí)行文件的過(guò)程:C語(yǔ)言源程序.c或.cpp編譯目標(biāo)程序.obj鏈接執(zhí)行程序.exe#include<stdio.h>#definePI3.14159voidmain(){floatr=4;printf(“s=%f\n”,PI*r*r);}預(yù)處理命令預(yù)處理本章討論之重點(diǎn)!2024/12/2335必須正確區(qū)別預(yù)處理命令和C語(yǔ)句、區(qū)別預(yù)處理和編譯,才能正確使用預(yù)處理命令。C語(yǔ)言與其他高級(jí)語(yǔ)言的一個(gè)重要區(qū)別是可以使用預(yù)處理命令和具有預(yù)處理的功能。C提供的預(yù)處理功能主要有以下三種:1.宏定義2.文件包含3.條件編譯分別用宏定義命令、文件包含命令、條件編譯命令來(lái)實(shí)現(xiàn)。為了與一般C語(yǔ)句相區(qū)別,這些命令以符號(hào)“#”開頭。語(yǔ)句尾不用分號(hào)作結(jié)束符,每條語(yǔ)句占一行。2024/12/23367.1宏定義
宏定義分為兩種:不帶參數(shù)的宏定義和帶參數(shù)的宏定義。
1、不帶參數(shù)的宏定義
一般形式
#define標(biāo)識(shí)符單詞串指令名稱宏名,被定義代表后面的單詞串
宏體,是宏的內(nèi)容文本
可缺省,表示宏名定義過(guò)或取消宏體
功能
用指定標(biāo)識(shí)符(宏名)代替字符序列(宏體)如
#defineYES1#defineNO0#definePI3.1415926#defineOUTprintf(“Hello,World”);#defineSIZE10#defineINT_STR
"%d"voidmain()
{inta[SIZE],i;for(i=0;i<SIZE;i++)scanf(INT_STR,&a[i]);for(i=SIZE-1;i>=0;i--)printf(INT_STR,a[i]);}宏定義voidmain()
{inta[10],i;for(i=0;i<10;i++)scanf("%d",&a[i]);for(i=10-1;i>=0;i--)printf("%d",a[i]);}預(yù)編譯處理后
注意:宏替換時(shí)僅僅是將源程序中與宏名相同的標(biāo)識(shí)符替換成宏的內(nèi)容文本,并不對(duì)宏的內(nèi)容文本做任何處理。2024/12/2337
宏定義注意事項(xiàng)
C程序員通常用大寫字母來(lái)定義宏名,以便與變量名區(qū)別。
如:#definePI3.14159
宏定義的位置任意,但一般放在函數(shù)外面。
宏定義時(shí),如果單詞串太長(zhǎng),需要寫多行,可以在行尾使用反斜線“\”續(xù)行符例如:#defineLONG_STRING"thisisaverylongstringthatis\usedasanexample"
宏名的作用域是從#define定義之后直到該宏定義所在文件結(jié)束
#undef可終止宏名作用域#undef標(biāo)識(shí)符#defineYES1voidmain(){……..}#undefYES#defineYES0voidmax(){……..}YES原作用域YES新作用域
宏定義可以嵌套定義,但不能遞歸定義
#defineR2.0#definePI3.14159#defineL2*PI*R(√)#defineSPI*R*R(√)#defineMM+10(×)
程序中字符串常量即雙引號(hào)中的字符,不作為宏進(jìn)行宏替換操作
#defineXYZthisisatestprintf("XYZ");輸出:XYZ,而不是:thisisatest。2024/12/2338
宏定義注意事項(xiàng)
宏定義一般以換行結(jié)束,不要用分號(hào)結(jié)束,以免引起不必要的錯(cuò)誤#definePI3.14;
a=PI*2*2;
預(yù)編譯處理后a=3.14;*2*2;
錯(cuò)誤!
宏可以被重復(fù)定義。
#defineN10
//第一次宏定義intf(){N的內(nèi)容是10return(N*N);}#defineN20
//第二次宏定義voidmain(){N的內(nèi)容是20printf("%d\n",N+f());}
在定義宏時(shí),如果宏是一個(gè)表達(dá)式,那么一定要將這個(gè)表達(dá)式用()括起來(lái),否則可能會(huì)引起非預(yù)期的結(jié)果。
#defineNUM110#defineNUM220#defineNUMNUM1+NUM2voidmain()
{inta=2,b=3;a*=NUM;b=b*NUM;printf("a=%d,b=%d\n",a,b);}voidmain()
{inta=2,b=3;a*=10+20;b=b*10+20;printf("a=%d,b=%d\n",a,b);}預(yù)編譯處理后輸出結(jié)果:a=60,b=50
()()()輸出結(jié)果:a=60,b=90
2024/12/23392、帶參數(shù)的宏定義
一般形式
#define標(biāo)識(shí)符(參數(shù)列表)單詞串參數(shù)表由一個(gè)或多個(gè)參數(shù)構(gòu)成,參數(shù)只有參數(shù)名,沒有數(shù)據(jù)類型符,參數(shù)之間用逗號(hào)隔開,參數(shù)名必須是合法的標(biāo)識(shí)符通常會(huì)引用宏的參數(shù)
例:
#defineS(a,b)a*b………..area=S(3,2);宏展開:area=3*2;宏展開:形參用實(shí)參換,其它字符保留宏體及各形參外一般應(yīng)加括號(hào)()不能加空格例
#defineS(r)PI*r*r相當(dāng)于定義了不帶參宏S,代表字符串“(r)PI*r*r”
例
#definePOWER(x)x*xx=4;y=6;z=POWER(x+y);宏展開:z=x+y*x+y;一般寫成:#definePOWER(x)((x)*(x))宏展開:
z=((x+y)*(x+y));2024/12/2340#defineMAX(x,y)(x)>(y)?(x):(y)…….voidmain(){inta,b,c,d,t;…….t=MAX(a+b,c+d);……}宏展開:t=(a+b)>(c+d)?(a+b):(c+d);intmax(intx,inty){return(x>y?x:y);}voidmain(){inta,b,c,d,t;…….t=max(a+b,c+d);………}【例】用宏定義和函數(shù)實(shí)現(xiàn)同樣的功能2024/12/2341帶參的宏與函數(shù)區(qū)別帶參宏函數(shù)處理時(shí)間編譯時(shí)程序運(yùn)行時(shí)參數(shù)類型無(wú)類型問題定義實(shí)參、形參類型處理過(guò)程不分配內(nèi)存,簡(jiǎn)單的字符置換分配內(nèi)存,先求實(shí)參值,再代入形參程序長(zhǎng)度變長(zhǎng)不變運(yùn)行速度不占運(yùn)行時(shí)間調(diào)用和返回占時(shí)間2024/12/23427.2文件包含處理過(guò)程
功能一個(gè)源文件可將另一個(gè)源文件的內(nèi)容全部包含進(jìn)來(lái)
一般形式#define<包含文件名>或
#define“包含文件名”
預(yù)編譯時(shí),用被包含文件的內(nèi)容取代該預(yù)處理命令,再對(duì)“包含”后的文件作一個(gè)源文件編譯<>:
直接到系統(tǒng)指定的“文件包含目錄”去查找被包含的文件“
”:系統(tǒng)首先到當(dāng)前目錄下查找被包含文件,如果沒找到,再到系統(tǒng)指定的“文件包含目錄”去查找。
預(yù)編譯處理后A源文件prg1.cpp#include"prg1.cpp"
B源文件prg2.cppBA新源文件prg2.cpp2024/12/2343文件包含舉例:#include"head.h"
#include"func.cpp"
voidmain(){inta,b,c;a=getnum();b=getnum();c=max(max(a,b),NUM);printf("MAX=%d\n",c);}(stdio.h文件中的內(nèi)容)
#defineNUM10intmax(intx,inty){return(x>y?x:y);}intgetnum(){inta;scanf("%d",&a)return(a);}voidmain(){inta,b,c;a=getnum();b=getnum();c=max(max(a,b),NUM);printf("MAX=%d\n",c);}#include<stdio.h>#defineNUM10intmax(intx,inty){return(x>y?x:y);}intgetnum(){inta;scanf("%d",&a)return(a);}預(yù)編譯處理后2024/12/2344文件包含的優(yōu)點(diǎn):
一個(gè)大程序,通常分為多個(gè)模塊,并由多個(gè)程序員分別編程。有了文件包含處理功能,就可以將多個(gè)模塊共用的數(shù)據(jù)(如符號(hào)常量和數(shù)據(jù)結(jié)構(gòu))或函數(shù),集中到一個(gè)單獨(dú)的文件中(如上例中的文件head.h和func.cpp)。這樣,凡是要使用其中數(shù)據(jù)或調(diào)用其中函數(shù)的程序員,只要使用文件包含處理功能,將所需文件包含進(jìn)來(lái)即可,不必再重復(fù)定義它們,從而減少重復(fù)勞動(dòng)。文件包含的幾點(diǎn)說(shuō)明
常用在文件頭部的被包含文件,稱為“標(biāo)題文件”或“頭部文件”,常以.h(head)作為后綴,簡(jiǎn)稱頭文件。在頭文件中,除可包含宏定義外,還可包含外部變量定義、結(jié)構(gòu)類型定義等。
一條包含命令,只能指定一個(gè)被包含文件。如果要包含n個(gè)文件,則要用n條包含命令。
文件包含可以嵌套,即被包含文件中又包含另一個(gè)文件。2024/12/23457.3條件編譯根據(jù)一定的條件去編譯源文件的不同部分,這就是條件編譯。1、#if~#endif形式
格式:#if
條件1
程序段1#elif條件2
程序段2……#else
程序段n#endif常量表達(dá)式。通常會(huì)用到宏名,條件可以不加括號(hào)“()”
#elif和#else可以沒有
#endif必須存在,它是#if命令的結(jié)尾
如果條件1為真就編譯程序段1,否則如果條件2為真就編譯程序段2,…,如果各條件都不為真就編譯程序段n。
作用:
#if和#elif常常與defined命令配合使用,defined命令的格式為:
defined(宏名)或defined宏名功能:判斷某個(gè)宏是否已經(jīng)定義,如果已經(jīng)定義,defined命令返回1,否則返回0。Defined命令只能與#if或#elif配合使用,不能單獨(dú)使用。例如:#ifdefined(USA)的含義是“如果定義了宏USA”。
2024/12/2346例:下面的程序利用ACTIVE_COUNTRY定義貨幣的名稱
#defineUSA0#defineENGLAND1#defineFRANCE2#defineACTIVE_COUNTRYUSA
#ifACTIVE_COUNTRY==USA
char*currency=“dollar”;
//有效
#elifACTIVE_COUNTRY==ENGLANDchar*currency="pound"
;#elsechar*currency="france"
;#endifvoidmain(){floatprice1,price2,sumprice;scanf("%f%f",&price1,&price2);sumprice=price1+price2;printf("sum=%.2f%s",sumprice,currency);}char*currency=“dollar”;
voidmain(){floatprice1,price2,sumprice;scanf("%f%f",&price1,&price2);sumprice=price1+price2;printf("sum=%.2f%s",sumprice,currency);}預(yù)編譯處理后2024/12/23472、#ifdef~#endif形式
格式:#ifdef宏名程序段1#else
程序段2#endif等價(jià)于“#ifdefined(宏名)”
在#ifdef和#else之間可以加多個(gè)#elif命令如果宏名已被#define行定義,則編譯程序段1,否則編譯程序段2
作用:#defineINTEGER#ifdefINTEGER
intadd(intx,inty)//有效
{return(x+y);}#elsefloatadd(floatx,floaty){return(x+y);}#endifvoidmain(){#ifdefINTEGER
inta,b,c;//有效
scanf("%d%d",a,b);printf("a+b=%d\n",add(a,b));#elsefloata,b,c;scanf("%f%f",a,b);printf("a+b=%f\n",add(a,b));#endif}intadd(intx,inty)//有效
{return(x+y);}voidmain(){inta,b,c;//有效
scanf("%d%d",a,b);printf("a+b=%d\n"
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年地產(chǎn)項(xiàng)目環(huán)保評(píng)估居間合同范本3篇
- 2024年食品研發(fā)代工生產(chǎn)及品牌授權(quán)協(xié)議2篇
- 2025年度消防技術(shù)服務(wù)與勞務(wù)派遣合作協(xié)議3篇
- 2025演出服務(wù)合同2
- 二零二五年度農(nóng)產(chǎn)品加工企業(yè)股權(quán)轉(zhuǎn)讓價(jià)格確認(rèn)協(xié)議3篇
- 2025年家長(zhǎng)學(xué)校學(xué)生安全責(zé)任協(xié)議共保學(xué)生平安2篇
- 二零二五年家居建材市場(chǎng)攤位租賃合同范本6篇
- 2025采購(gòu)合同示例
- 2024版施工項(xiàng)目承攬協(xié)議樣本版
- 2024新版殯葬業(yè)務(wù)合作合同范本版B版
- 2024年有限合伙股權(quán)代持
- 廣東珠海市駕車沖撞行人案件安全防范專題培訓(xùn)
- 花城版一年級(jí)上冊(cè)音樂 第3課 《國(guó)旗國(guó)旗真美麗》(教案)
- 2024年四川高校對(duì)口招生考試中職英語(yǔ)試卷真題(含答案)
- 食品質(zhì)量安全法律法規(guī)培訓(xùn)
- 醫(yī)療儀器安裝與調(diào)試方案
- 陜西省陜西師大附中2025屆高一物理第一學(xué)期期末統(tǒng)考模擬試題含解析
- 人教版2024年小學(xué)二年級(jí)上學(xué)期語(yǔ)文期末考試往年真題
- 2024年保安員證考試題庫(kù)及答案(共130題)
- 2024壓鑄機(jī)安全技術(shù)規(guī)范
- 期末綜合素養(yǎng)評(píng)價(jià) (三)(試題)-2024-2025學(xué)年一年級(jí)上冊(cè)數(shù)學(xué)
評(píng)論
0/150
提交評(píng)論