C語言程序設(shè)計新視角-編譯預(yù)處理_第1頁
C語言程序設(shè)計新視角-編譯預(yù)處理_第2頁
C語言程序設(shè)計新視角-編譯預(yù)處理_第3頁
C語言程序設(shè)計新視角-編譯預(yù)處理_第4頁
C語言程序設(shè)計新視角-編譯預(yù)處理_第5頁
已閱讀5頁,還剩33頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

編譯預(yù)處理NewPerspectiveforCProgranmming【主要內(nèi)容】

?預(yù)處理的概念及特點;

?宏的定義及使用;

?文件包含的含義及使用;

?條件編譯的規(guī)則及方法?!緦W(xué)習(xí)目標】

?領(lǐng)會文件包含的使用及效果,能夠使用#include來開發(fā)較大的程序;

?能夠使用#define創(chuàng)建普通的宏;

?理解條件編譯。

19.1宏定義29.2文件包含39.3條件編譯49.4本章小結(jié)目錄CONTENTS

圖9.1源程序生成執(zhí)行文件的過程用C語言進行編程的時候,可以在源程序中包括一些編譯命令,以告訴編譯器對源程序如何進行編譯。程序編譯時,先處理這些編譯命令,然后再進行源程序編譯,所以,這些編譯命令也被稱為編譯預(yù)處理。源程序生成執(zhí)行文件的過程見圖9.1。預(yù)處理命令字宏定義 #define、#undef

文件包含 #include

條件編譯 #if、#ifdef、#else、#elif、#endif

預(yù)處理命令都是以“#”開頭的。實際上,編譯預(yù)處理命令不能算是C語言的一部分,但它擴展了C程序設(shè)計的能力,合理地使用編譯預(yù)處理功能,可以使得編寫的程序便于閱讀、修改、移植和調(diào)試。

注意:預(yù)處理命令不是C語句,不能用分號結(jié)束19.1宏定義29.2文件包含39.3條件編譯49.4本章小結(jié)目錄CONTENTS9.1宏定義如果程序中有多個地方要用到同一個常量值,而且這些值在測試時有可能要根據(jù)需要改變,方便的做法應(yīng)該是設(shè)一個專門的符號,只給這個符號在最初定義的地方賦值即可。在這個常量值需要改的時候只要改定義處的值就行了,不用從代碼中一處一處地改,這樣就不會因為漏掉某個地方而導(dǎo)致程序出錯。這相當于做了一個文本替換的工作9.1.1簡單的宏定義#define<宏名><字符串>define是宏定義命令的關(guān)鍵字;<宏名>是一個標識符;<字符串>可以是常數(shù)、表達式、格式串等。

說明:

(1)在程序被編譯的時候,如果遇到宏名,先將宏名用指定的字符串替換,然后再進行編譯。

(2)ANSI標準將替換過程稱為宏替換。

(3)C語言程序普遍使用大寫字母定義標識符。這種約定可使得讀程序時很快發(fā)現(xiàn)哪里有宏替換。

(4)最好是將所有的#define放到文件的開始處或獨立的文件中(用#include訪問)?!纠?-1】宏的例子1

用串替換標識符

#defineMAX128

voidmain()

{

intmax=MAX;

}編譯器處理時,會直接把MAX替換成128。注意是文本替換,而不是變量賦值,程序中自始至終都不存在MAX這個量,相當于是用“查找→替換”功能查找MAX,并替換成128。

【例9-2】宏的例子2用串替換標識符。

#defineTRUE 1

#defineFALSE 0

printf("%d%d%d",F(xiàn)ALSE,TRUE,TRUE+1);

輸出:012【例9-3】宏的例子3宏代換的最一般用途是定義常量的名字。

#defineMAX_SIZE100

float balance[MAX_SIZE];

【例9-4】宏的例子4宏替換僅僅是以串代替標識符,而非字符串。

#defineE_MS"standarderroroninput\n"

printf(E_MS);

編譯后printf語句實際是如下形式:

printf("standarderroroninput\n");

#defineXYZ thisisatest

printf("XYZ");/*此處"XYZ"為字符串*/

該段不打印"thisisatest"而打印"XYZ"。9.1.2帶參數(shù)的宏定義

其中:

(1)<宏名>是一個標識符;

(2)(參數(shù)表)中的參數(shù)可以是一個,也可以是多個,當有多個參數(shù)的時候,每個參數(shù)之間用逗號分隔;

(3)<宏體>是被替換用的字符串,宏體中的字符串是由參數(shù)表中的各個參數(shù)組成的表達式。

#define<宏名>(參數(shù)表)<宏體>

#define命令的另一個特性是,宏名可以取參量?!纠?-5】宏的例子5

#defineSUB(a,b)a-b

result=SUB(2,3);被替換為:result=2-3;

result=SUB(x+1,y+2);被替換為:result=x+1-y+2;

帶參數(shù)的宏定義與函數(shù)類似,在宏替換時,就是用實參來替換<宏體>中的形參?!纠?-6】宏的例子6

#defineMIN(a,b) (a<b)?a:bintmain()

{

int x,y;

x=10;

y=20;

printf("theminimumis:%d",MIN(x,y));

return0;

}

當編譯該程序時,由MIN(a,b)定義的表達式被替換,x和y用作操作數(shù),即printf語句被代換后取如下形式:

printf("theminimumis:%d",(x<y)?x:y);

用宏替換代替實在的函數(shù)的一大好處是宏替換增加了代碼的執(zhí)行速度,因為不存在函數(shù)調(diào)用的開銷。但增加速度的代價是,由于重復(fù)編碼而增加了程序長度。表9.1宏與函數(shù)的區(qū)別

雖然帶參數(shù)的宏定義和帶參數(shù)的函數(shù)很相似,但它們還是有本質(zhì)上的區(qū)別,具體參見表9.1。

當一個函數(shù)中對較長變量(一般是結(jié)構(gòu)的成員)有較多引用時,可以用一個意義相當?shù)暮甏?。這樣可以增加編程效率和程序的可讀性。19.1宏定義29.2文件包含39.3條件編譯49.4本章小結(jié)目錄CONTENTS9.2文件包含

文件包含命令是把指定的文件插入該命令行位置,從而把指定的文件和當前的源程序文件連成一個源文件。文件包含命令格式#include<文件名>#include"文件名"或其中:

(1)include是關(guān)鍵字。

(2)文件名是指被包含的文件全名。如果文件名以尖括號括起,則在編譯時將會在指定的目錄下查找此頭文件;文件名以雙引號括起,則在編譯時會首先在當前的源文件目錄中查找該頭文件,若找不到才會到系統(tǒng)的指定目錄下去查找。

圖9.2文件包含處理

預(yù)編譯時,用被包含文件的內(nèi)容取代該預(yù)處理命令,再把“包含”后的文件當做一個源文件進行編譯,處理示意圖見圖9.2。文件包含的用處同系統(tǒng)多個文件,公用信息可單獨組成一個包含文件當一個程序比較大時,可以把它分為多個功能相對獨立的小程序,由多個程序員分別編程。這些小程序中有些公用的信息等可單獨組成一個文件,在其他文件的開頭用包含命令包含該文件即可使用。如符號常量、函數(shù)的定義等放到一個.h文件中(即文件擴展名為h的文件,稱之為頭文件)。在其他文件的開頭用包含命令包含該頭文件,這樣,可避免在每個文件開頭都書寫那些公用量,從而節(jié)省時間,并減少出錯。頭文件可自己編寫/系統(tǒng)提供例如stdio.h便是一個由系統(tǒng)提供的、有關(guān)輸入/輸出操作信息的頭文件?!纠?-7】編輯一個文件,在另外一個文件中被包含。voidfun(){printf("Hello!");}#include“stdio.h"#include"file1.c"intmain(){fun();return0;}保存為file1.c保存為file2.c包含文件file1.c注:file1.c和file2.c要在同一路徑下,只要編譯運行file2.c即可19.1宏定義29.2文件包含39.3條件編譯49.4本章小結(jié)目錄CONTENTS9.3條件編譯條件編譯命令可以使得編譯器按不同的條件去編譯程序不同的部分,產(chǎn)生不同的目標代碼文件。通過條件編譯命令,某些程序代碼要在滿足一定條件下才被編譯,否則將不被編譯。條件編譯命令格式一商業(yè)軟件公司廣泛應(yīng)用條件編譯來提供和維護某一程序的各種用戶版本。#ifdef標識符

程序段1

#else

程序段2

#endififdef、else和endif都是關(guān)鍵字。程序段1和程序段2是由若干預(yù)處理命令和語句組成的。它的功能是,如果標識符已被#define命令定義過,則對程序段1進行編譯;否則對程序段2進行編譯。本格式中的#else也可以沒有【例9-8】條件編譯命令的例子1

1 #include<stdio.h>

2 #defineTIME

3 intmain()

4 {

5

#ifdefTIME

6

printf("Nowbegintowork\n");

7

#else

8

printf("Youcanhavearest\n");

9 #endif

10 return0;

11 }

TIME是否已被#define語句定義過來決定編譯哪一個printf語句。如果定義過,則編譯第6行語句,否則編譯第8行語句。本例TIME已經(jīng)定義過輸出的結(jié)果為:Nowbegintowork條件編譯命令格式二#ifndef標識符

程序段1

#else

程序段2

#endif格式二與格式一形式上的區(qū)別在于ifdef關(guān)鍵字換成了ifndef關(guān)鍵字,其功能是:如果標識符未被#define命令定義過,則對程序段1進行編譯;否則對程序段2進行編譯。這與格式一的功能正好相反。條件編譯命令格式二

#ifndefNULL

#defineNULL((void*)0)

#endif

本段代碼能夠保證符號NULL只有一次定義為((void*)0)。

條件編譯命令格式三#if常量表達式程序段1#else

程序段2#endif

if、else和endif是關(guān)鍵字。程序段1和程序段2都是由若干條預(yù)處理命令和語句組成的。它的功能是:如常量表達式的值為真(true),則對程序段1進行編譯;否則對程序段2進行編譯。因此可以使程序在不同條件下完成不同的功能。【例9-9】條件編譯命令的例子2

1 #include<stdio.h>

2 #defineR1

3 intmain()

4 {

5 floatc,s;

6 printf("inputanumber:");

7 scanf("%f",&c);

8 #ifR

9 s=3.14*c*c;

10 printf("areaofroundis:%f\n",s);

11 #else

12 s=c*c;

13 printf("areaofsquareis%f\n",s);

14 #endif

15 return0;

16 }

如果常量表達式R為真,則編譯第9、10行語句,否則編譯第12、13行語句

多種編譯選擇的情況

#if常量表達式1

程序段1

#elif常量表達式2

程序段2

#elif常量表達式3

程序段3

#else

程序段n+1

#endif【例9-10】條件編譯的應(yīng)用場合便于程序的移植#ifdefTURBO_C…

//TurboC獨有的內(nèi)容#endif#ifdefBORLAND_C…

//BorlandC獨有的內(nèi)容#endif#ifdefVISUAL_C…

//VisualC獨有的內(nèi)容#endif#defineDEBUG……#ifdefDEBUGprintf(……);//臨時結(jié)果#endif若希望生成BorlandC版本,添加:

#defineBORLAND_C若希望生成VisualC版本,添加:

#define

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論