第8章 C語言編譯預(yù)處理_第1頁
第8章 C語言編譯預(yù)處理_第2頁
第8章 C語言編譯預(yù)處理_第3頁
第8章 C語言編譯預(yù)處理_第4頁
第8章 C語言編譯預(yù)處理_第5頁
已閱讀5頁,還剩23頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第八章編譯預(yù)處理作用:對源程序編譯之前做一些處理,生成擴(kuò)展C源程序種類宏定義#define文件包含#include條件編譯#if--#else--#endif等格式:“#”開頭占單獨書寫行語句尾不加分號如if(x==YES)printf(“correct!\n”);elseif(x==NO)printf(“error!\n”);展開后:if(x==1)printf(“correct!\n”);elseif(x==0)printf(“error!\n”);8.1

宏定義8.1.1不帶參數(shù)宏定義一般形式:#define宏名[宏體]功能:用指定標(biāo)識符(宏名)代替字符序列(宏體)宏展開:預(yù)編譯時,用宏體替換宏名---不作語法檢查如#defineYES1#defineNO0#definePI3.1415926#defineOUTprintf(“Hello,World”);宏體可缺省,表示宏名定義過或取消宏體定義位置:任意(一般在函數(shù)外面)作用域:從定義命令到文件結(jié)束#undef可終止宏名作用域格式:

#undef

宏名例#defineYES1main(){……..}#undefYES#defineYES0max(){……..}YES原作用域YES新作用域宏定義可嵌套,不能遞歸例#defineMAXMAX+10(

)引號中的內(nèi)容與宏名相同也不置換例#definePI3.14159printf(“2*PI=%f\n”,PI*2);宏展開:printf(“2*PI=%f\n”,3.14159*2);宏定義中使用必要的括號()例#defineWIDTH80#defineLENGTH

WIDTH+40

var=LENGTH*2;宏展開:var=80+40*2;()()例#defineWIDTH80#defineLENGTH

WIDTH+40

var=LENGTH*2;宏展開:var=80+40*2;

案例分析1(8.1)#definePRICE30main(){

int

num,total;num=10;total=num*PRICE;

printf(“total=%d”,total);}程序運(yùn)算結(jié)果:total=300當(dāng)價格發(fā)生變化時,只需要修改宏定義,就可以做到一改而全改案例分析2#definePI

3.1415926

main(){floatl,s,r,v;

printf("input

raDiuS∶");

scanf("%f",&r);

l=2.0*PI*r;

s=PI*r*r;

v=3.0/4*PI*r*r*r;

printf("l=%10.4f\nS=%10.4f\nv=%10.4f\n",l,s,v);}使用宏名代替一個字符串,可以用一個簡單的名字來代替一個長的字符串。減少了程序中重復(fù)書寫某些字符串的工作里昂,既不易出錯,又提高了程序的可移植性。注意:如果字符串一行內(nèi)裝不下,可以放到下一行,只要在上一行的結(jié)尾處放一個反斜杠(\)即可。

例如:#defineLONG_STING“thisis\averylongstringthatisused.” 案例分析3#include<stdio.h>#define M 3#define N M+1#define NN N*N/2main(){printf(“%d\n”,NN);printf(“%d\n”,5*NN);}第一個printf的輸出為6

第二個printf輸出值為18

說明:#define命令出現(xiàn)在程序中函數(shù)的外面,宏名的有效范圍為定義命令之后到本源文件結(jié)束.

課堂練習(xí)8.1-7)、15)8.12帶參數(shù)宏定義一般形式:#define宏名(參數(shù)表)宏體例#defineS(r)PI*r*r相當(dāng)于定義了不帶參宏S,代表字符串“(r)PI*r*r”宏展開:形參用實參換,其它字符保留宏體及各形參外一般應(yīng)加括號()例#defineS(a,b)a*b………..area=S(3,2);宏展開:area=3*2;不能加空格例#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));(1)程序中宏名后的實參與命令行中宏名后的虛參按位置一一對應(yīng)。(2)用實參代替字符串中的虛參,注意只是字符串的代換,不含計算過程。(3)把用實參替換的字符串,替換程序中的宏名。[例8.3]寫出下列程序運(yùn)行的結(jié)果:

#definePT 3.5#defineS(x) PT*x*xmain()

{

inta=1,b=2;

printf(”%4.1f\n”,S(a+b));

}案例分析1說明:

(1)對帶參數(shù)的宏的展開只是將語句中的宏名內(nèi)的實參字符串代替#define命令行中的虛參,不能人為的增加括號和計算功能。(2)由子宏定義時,宏名與其所代替的字符串之間有一個或一個以上的空格。

#defineMAX(x,y)(x)>(y)?(x):(y)…….main(){inta,b,c,d,t;…….t=MAX(a+b,c+d);……}宏展開:t=(a+b)>(c+d)?(a+b):(c+d);int

max(int

x,inty){return(x>y?x:y);}main(){inta,b,c,d,t;…….t=max(a+b,c+d);………}例用宏定義和函數(shù)實現(xiàn)同樣的功能<>案例分析2帶參的宏與函數(shù)區(qū)別帶參宏函數(shù)處理過程不分配內(nèi)存簡單的字符置換分配內(nèi)存先求實參值,再代入形參處理時間編譯時程序運(yùn)行時參數(shù)類型無類型問題定義實參,形參類型程序長度變長不變運(yùn)行速度不占運(yùn)行時間調(diào)用和返回占時間<>課堂練習(xí)1

定義一個帶參數(shù)的宏,使兩個參數(shù)的值互換,并編一個程序,輸入兩個整數(shù)作為使用宏時的參數(shù),輸出已經(jīng)交換的兩個值。#defineSWAP(a,b) t=b;b=a;a=t;main(){

int

a,b,t;

printf(“請輸入兩個整數(shù):”);

scanf(“%d,%d”,&a,&b);

printf(“\n原來得數(shù)據(jù)為:a=%d,b=%d\n”,a,b);

SWAP(a,b);

printf(“交換結(jié)果為:a=%d,b=&d\n”,a,b);}課堂練習(xí)2分析程序定義一個頭文件“format.h”:在該文件中定義三種輸出格式用戶文件用#include語句將該文件包含起來;好處:避免重復(fù)工作;一改而全改;注意:宏定義修改后,序重新進(jìn)行編譯;8.2

文件包含功能:一個源文件可將另一個源文件的內(nèi)容全部包含進(jìn)來一般形式:#include“文件名”或#include<文件名>#include“file2.c”file1.cfile2.cfile1.cfile2.cABA處理過程:預(yù)編譯時,用被包含文件的內(nèi)容取代該預(yù)處理命令,再對“包含”后的文件作一個源文件編譯<>直接按標(biāo)準(zhǔn)目錄搜索“”先在當(dāng)前目錄搜索,再搜索標(biāo)準(zhǔn)目錄可指定路徑被包含文件內(nèi)容源文件(*.c)頭文件(*.h)宏定義數(shù)據(jù)結(jié)構(gòu)定義函數(shù)說明等文件包含可嵌套#include“file2.c”file1.cAfile3.cC#include“file3.c”file2.c

Bfile1.cAfile3.cfile2.c文件包含的使用C語言標(biāo)準(zhǔn)庫函數(shù)的使用#include<stdio.h>自己定義文件系統(tǒng)開發(fā)時,某單位人員往往使用一組固定的符號常量,可以把這些宏定義組成一個文件,然后每人都可以使用#include命令把這些符號常量包含到自己的程序中,從而避免重復(fù)工作;此外可做到一改而全改;案例分析

[例8.7]頭文件應(yīng)用實例(1)文件print_format.h#definePRprintf#defineNL“\n”#defineD“%d”#defineD1DNL#defineD2DDNL#defineD3DDDNL#defineD4DDDDNL#defineS“%s”(2)文件file1.c#include”print_format.h”main(){int

a,b,c,d;charstring[]=“CHINA”;

a=1;b=2;c=3,d=4;PR(D1,a);PR(D2,a,b);PR(D3,a,b,c);PR(D4,a,b,c,d);PR(S,sting);}8.3條件編譯C語言也允許有選擇的對源程序的某一部分進(jìn)行編譯,這就是“條件編譯”。

條件編譯有以下三種形式:#ifdef<標(biāo)識符>

程序段1#else

程序段2#endif#ifndef<標(biāo)識符>

程序段1#else

程序段2#endif#if表達(dá)式程序段1#else

程序段2#endif#ifdef<標(biāo)識符>

程序段1#else

程序段2#endif8.3.1條件編譯語句1它的功能是:當(dāng)指定標(biāo)識符已經(jīng)被定義過(一般用#define命令定義),則對程序段1進(jìn)行編譯,否則對程序段2進(jìn)行編譯。

案例分析1條件編譯對于提高C源程序的通用性是很有好處的。如果一個C源程序在不同計算機(jī)系統(tǒng)上運(yùn)行,而不同的計算機(jī)又有一定的差異(例如,有的機(jī)器以16位(2個字節(jié))來存放一個整數(shù),而有的則以32位存放一個整數(shù)),這樣往往需要對源程序作必要的修改,這就降低了程序的通用性。可以用以下的條件編譯來處理:#ifdef

COMPUTER-A#define

INTEGER-SIZE16#else#define

INTEGER-SIZE32#endif即如果COMPUTER-A在前面已被定義過,則編譯下面的命令行:#defineINTEGER-SIZE16否則,編譯下面的命令行:#defineINTEGER-SIZE32案例分析2例如,在調(diào)試程序時,常常希望輸出一些所需的信息,而在調(diào)試完成后不再輸出這些信息??梢栽谠闯绦蛑胁迦胍韵碌臈l件編譯段:#ifdefDEBUGprintf("x=%D,y=%D,Z=%D\n",x,y,Z);#endif如果在它的前面有以下命令行:#defineDEBUG則在程序運(yùn)行時輸出x、y、Z的值,以便調(diào)試時分析。8.3.2條件編譯語句2

#ifndef<標(biāo)識符>

程序段1#else

程序段2#endif它的功能是:若指定的標(biāo)識符未被定義則編譯程序段1,否則編譯程序段2。這種形式的功能和第一種形式的功能相反。

例如:

#ifndefLIST

printf("x=%d,y=%d,z=%d\n",x,y,z);

#endif其預(yù)處理功能為:如在此之前未對LIST定義,則輸出x,y,z的值。在程序調(diào)試時,不對LIST定義,此時輸出x,y,z的值,調(diào)試結(jié)束后,在運(yùn)行上述程序段之前,加以下面的命令行:

#define LIST則不輸出x,y,z的值。8.3.3條件編譯語句3#if表達(dá)式程序段1#else

程序段2#endif

它的功能是:當(dāng)指定的表達(dá)式為真(非零)時.編譯程序段1,否則編譯程序段2。應(yīng)用這種條件編譯的方法,可以事先給定某一條件:使程序在不同的條件下執(zhí)行不同的功能。案例分析

[例8.8]用條件編譯方法實現(xiàn)以下功能:

輸入一行電報文字,可以任選兩種輸出,一為原文輸出;一為將字母變成其下一字母(如‘a(chǎn)’變成’b’,…,’z’變成‘a(chǎn)’,其它字符不變)。用#define命令來控制是否要譯成密碼。例如:

#defineCHANGE1

則輸出密碼。若

#defineCHANGE0

則不譯成密碼,按原碼輸出。#include<stdio.h>#defineMAX80#defineCHANGE1main(){charstr[MAX];

inti;

printf(“請輸入文本行:\n”);

scanf(“%s”,str);

#if(CHANGE){for(i=0;i<MAX;i++) {

if(str[i]!=’\0’)

溫馨提示

  • 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

提交評論