第10章 預(yù)處理命令_第1頁
第10章 預(yù)處理命令_第2頁
第10章 預(yù)處理命令_第3頁
第10章 預(yù)處理命令_第4頁
第10章 預(yù)處理命令_第5頁
已閱讀5頁,還剩16頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第10章預(yù)處理命令制作人:王敬華第10章:預(yù)處理命令

學(xué)習(xí)的意義

語言程序設(shè)計教程第二版第十章預(yù)處理命令CC語言的一個重要特征是它的預(yù)處理功能。我們知道,一個高級語言源程序在計算機(jī)上運(yùn)行,必須先用編譯程序?qū)⑵浞g為機(jī)器語言。編譯包括詞法分析、語法分析、代碼生成、代碼優(yōu)化等步驟,有時在編譯之前還要做某些預(yù)處理工作,如去掉注釋,變換格式等。C語言允許在源程序中包含預(yù)處理命令,在正式編譯之前(詞法分析之前)系統(tǒng)先對這些命令進(jìn)行“預(yù)處理”,然后整個源程序再進(jìn)行通常的編譯處理。從語法上講,這些預(yù)處理命令不是C語言的一部分,但使用它們卻擴(kuò)展了C語言程序設(shè)計的環(huán)境,可以簡化程序開發(fā)過程,提高程序的可讀性,也更有利于移植和調(diào)試C語言程序。本章主要介紹宏定義、文件包括和條件編譯等預(yù)處理命令。學(xué)習(xí)的意義

源程序生成執(zhí)行文件的過程:C語言源程序.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)!語言程序設(shè)計教程第二版第十章預(yù)處理命令C學(xué)習(xí)目標(biāo)

學(xué)習(xí)內(nèi)容

預(yù)處理命令簡介宏定義不帶參數(shù)的宏定義帶參數(shù)的宏定義文件包括條件編譯本章小結(jié)掌握#include、#define、#if、#ifdef、#else、#ifndef和

#endif等命令的用法;掌握宏定義和宏替換的一般方法;掌握包含文件的處理方法;了解條件編譯的作用和實現(xiàn)方法。語言程序設(shè)計教程第二版第十章預(yù)處理命令C10.1預(yù)處理命令簡介

預(yù)處理命令:C源程序中以#開頭、以換行符結(jié)尾的行

種類:宏定義#define、#undef

文件包含#include

條件編譯#if、#ifdef、#else、#elif、#endif等其他

#line、#error、#program等本章主要討論的內(nèi)容!格式:“#”開頭占單獨(dú)書寫行語句尾不加分號語言程序設(shè)計教程第二版第十章預(yù)處理命令C10.2宏定義

宏定義分為兩種:不帶參數(shù)的宏定義和帶參數(shù)的宏定義。

1、不帶參數(shù)的宏定義一般形式

#define標(biāo)識符單詞串指令名稱宏名,被定義代表后面的單詞串

宏體,是宏的內(nèi)容文本

可缺省,表示宏名定義過或取消宏體功能

用指定標(biāo)識符(宏名)代替字符序列(宏體)如#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ù)編譯處理后

注意:宏替換時僅僅是將源程序中與宏名相同的標(biāo)識符替換成宏的內(nèi)容文本,并不對宏的內(nèi)容文本做任何處理。語言程序設(shè)計教程第二版第十章預(yù)處理命令C宏定義注意事項

C程序員通常用大寫字母來定義宏名,以便與變量名區(qū)別。

如:#definePI3.14159宏定義的位置任意,但一般放在函數(shù)外面。

宏定義時,如果單詞串太長,需要寫多行,可以在行尾使用反斜線“\”續(xù)行符例如:#defineLONG_STRING"thisisaverylongstringthatis\usedasanexample"宏名的作用域是從#define定義之后直到該宏定義所在文件結(jié)束

#undef可終止宏名作用域#undef標(biāo)識符#defineYES1voidmain(){……..}#undefYES#defineYES0voidmax(){……..}YES原作用域YES新作用域

宏定義可以嵌套定義,但不能遞歸定義

#defineR2.0#definePI3.14159#defineL2*PI*R(√)#defineSPI*R*R(√)#defineMM+10(×)程序中字符串常量即雙引號中的字符,不作為宏進(jìn)行宏替換操作

#defineXYZthisisatestprintf("XYZ");輸出:XYZ,而不是:thisisatest。語言程序設(shè)計教程第二版第十章預(yù)處理命令C宏定義注意事項

宏定義一般以換行結(jié)束,不要用分號結(jié)束,以免引起不必要的錯誤#definePI3.14;

a=PI*2*2;

預(yù)編譯處理后a=3.14;*2*2;

錯誤!宏可以被重復(fù)定義。

#defineN10

//第一次宏定義intf(){N的內(nèi)容是10return(N*N);}#defineN20

//第二次宏定義voidmain(){N的內(nèi)容是20printf("%d\n",N+f());}在定義宏時,如果宏是一個表達(dá)式,那么一定要將這個表達(dá)式用()括起來,否則可能會引起非預(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

語言程序設(shè)計教程第二版第十章預(yù)處理命令C2、帶參數(shù)的宏定義一般形式

#define標(biāo)識符(參數(shù)列表)單詞串參數(shù)表由一個或多個參數(shù)構(gòu)成,參數(shù)只有參數(shù)名,沒有數(shù)據(jù)類型符,參數(shù)之間用逗號隔開,參數(shù)名必須是合法的標(biāo)識符通常會引用宏的參數(shù)

例:#defineS(a,b)a*b………..area=S(3,2);宏展開:area=3*2;宏展開:形參用實參換,其它字符保留宏體及各形參外一般應(yīng)加括號()不能加空格例#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));語言程序設(shè)計教程第二版第十章預(yù)處理命令C#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ù)實現(xiàn)同樣的功能語言程序設(shè)計教程第二版第十章預(yù)處理命令C帶參的宏與函數(shù)區(qū)別帶參宏函數(shù)處理時間編譯時程序運(yùn)行時參數(shù)類型無類型問題定義實參、形參類型處理過程不分配內(nèi)存,簡單的字符置換分配內(nèi)存,先求實參值,再代入形參程序長度變長不變運(yùn)行速度不占運(yùn)行時間調(diào)用和返回占時間語言程序設(shè)計教程第二版第十章預(yù)處理命令C10.3文件包含處理過程功能一個源文件可將另一個源文件的內(nèi)容全部包含進(jìn)來一般形式#define<包含文件名>或#define“包含文件名”預(yù)編譯時,用被包含文件的內(nèi)容取代該預(yù)處理命令,再對“包含”后的文件作一個源文件編譯<>:直接到系統(tǒng)指定的“文件包含目錄”去查找被包含的文件“”:系統(tǒng)首先到當(dāng)前目錄下查找被包含文件,如果沒找到,再到系統(tǒng)指定的“文件包含目錄”去查找。

預(yù)編譯處理后A源文件prg1.cpp#include"prg1.cpp"

B源文件prg2.cppBA新源文件prg2.cpp語言程序設(shè)計教程第二版第十章預(yù)處理命令C文件包含舉例:#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ù)編譯處理后語言程序設(shè)計教程第二版第十章預(yù)處理命令C文件包含的優(yōu)點(diǎn):

一個大程序,通常分為多個模塊,并由多個程序員分別編程。有了文件包含處理功能,就可以將多個模塊共用的數(shù)據(jù)(如符號常量和數(shù)據(jù)結(jié)構(gòu))或函數(shù),集中到一個單獨(dú)的文件中(如上例中的文件head.h和func.cpp)。這樣,凡是要使用其中數(shù)據(jù)或調(diào)用其中函數(shù)的程序員,只要使用文件包含處理功能,將所需文件包含進(jìn)來即可,不必再重復(fù)定義它們,從而減少重復(fù)勞動。文件包含的幾點(diǎn)說明

常用在文件頭部的被包含文件,稱為“標(biāo)題文件”或“頭部文件”,常以.h(head)作為后綴,簡稱頭文件。在頭文件中,除可包含宏定義外,還可包含外部變量定義、結(jié)構(gòu)類型定義等。

一條包含命令,只能指定一個被包含文件。如果要包含n個文件,則要用n條包含命令。

文件包含可以嵌套,即被包含文件中又包含另一個文件。語言程序設(shè)計教程第二版第十章預(yù)處理命令C10.4條件編譯根據(jù)一定的條件去編譯源文件的不同部分,這就是條件編譯。1、#if~#endif形式格式:#if條件1程序段1#elif條件2程序段2……#else程序段n#endif常量表達(dá)式。通常會用到宏名,條件可以不加括號“()”

#elif和#else可以沒有

#endif必須存在,它是#if命令的結(jié)尾

如果條件1為真就編譯程序段1,否則如果條件2為真就編譯程序段2,…,如果各條件都不為真就編譯程序段n。作用:

#if和#elif常常與defined命令配合使用,defined命令的格式為:

defined(宏名)或defined宏名功能:判斷某個宏是否已經(jīng)定義,如果已經(jīng)定義,defined命令返回1,否則返回0。Defined命令只能與#if或#elif配合使用,不能單獨(dú)使用。例如:#ifdefined(USA)的含義是“如果定義了宏USA”。

語言程序設(shè)計教程第二版第十章預(yù)處理命令C例:下面的程序利用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ù)編譯處理后語言程序設(shè)計教程第二版第十章預(yù)處理命令C2、#ifdef~#endif形式格式:#ifdef宏名程序段1#else程序段2#endif等價于“#ifdefined(宏名)”

在#ifdef和#else之間可以加多個#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",add(a,b));}預(yù)編譯處理后語言程序設(shè)計教程第二版第十章預(yù)處理命令C3、#ifndef~#endif形式格式:#ifndef宏名程序段1#else程序段2#endif如果宏名沒被#define行定義,則編譯程序段1,否則編譯程序段2

作用:條件編譯與分支語句二者之間的差別:條件編譯是在預(yù)編譯時處理;而條件語句則是在程序運(yùn)行時處理。條件編譯中的條件不可以包含變量名,只能是常量表達(dá)式(通常包含宏名),可以不加括號;而條件語句中的條件是條件表達(dá)式,可以包含變量或函數(shù)等,并且必須加括號。例如:#defineN10intNUM=10;#ifNUM==10…#endif

錯誤,NUM是變量??筛臑椋?/p>

#ifN==10

語言程序設(shè)計教程第二版第十章預(yù)處理命令C條件編譯與分支語句二者之間的差別:條件編譯是將滿足編譯條件的程序代碼進(jìn)行編譯生成目標(biāo)代碼,不滿足編譯條件的程序代碼將不進(jìn)行編譯;而分支語句則是不管滿足條件的代碼,還是不滿足條件的代碼,都要編譯生成目標(biāo)代碼(包括分支語句本身),所以如果用條件語句來代替條件編譯命令,程序的目標(biāo)代碼將變長

條件編譯命令可以放在所有函數(shù)的外部,也可以放在某函數(shù)的內(nèi)部;但分支語句只能出現(xiàn)在某函數(shù)內(nèi)部。使用條件編譯的源程序使用分支語句的源程序#include<stdio.h>#include<stdio.h>#defineNUM10#defineNUM10voidmain()voidmain(){{程序代碼#ifNUM==10if(NUM==10)printf("NUMis10\n");printf("NUMis10\n");#elseelseprintf("NUMnotis10\n");printf("NUM

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論