分校C課件第15講編譯預處理18_第1頁
分校C課件第15講編譯預處理18_第2頁
分校C課件第15講編譯預處理18_第3頁
分校C課件第15講編譯預處理18_第4頁
分校C課件第15講編譯預處理18_第5頁
已閱讀5頁,還剩14頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、C C語言程序設計教程語言程序設計教程編寫組編寫組20072007年年1 1月月黃興鼎版權所有黃興鼎版權所有黃興鼎版權所有黃興鼎版權所有第十五講第十五講 編譯預處理編譯預處理編譯預處理編譯預處理文件包含文件包含宏定義宏定義無參無參有參有參條件編譯條件編譯程序設計舉例程序設計舉例C C語言程序設計語言程序設計/* (cw1401.c)輸出格式用宏定義免麻煩輸出格式用宏定義免麻煩*/#include #define P printf#define D %dn#define F %fnint main()int a=5, c=8;float b=3.8, d=9.7;P(D F,a,b);P(D F

2、,c,d); return 0;黃興鼎版權所有黃興鼎版權所有簡介簡介預處理預處理(preprocessing)在實施代碼轉換之前進行。在實施代碼轉換之前進行。包括:包括:包含其它文件包含其它文件定義宏定義宏有條件的編譯程序代碼有條件的編譯程序代碼預處理命令預處理命令(preprocessor directive)的格式的格式以以#開頭的一行(可以占多行)開頭的一行(可以占多行)#前面只能出現(xiàn)空白符前面只能出現(xiàn)空白符編譯預處理編譯預處理黃興鼎版權所有黃興鼎版權所有文件包含文件包含#include把所包含的文件的內(nèi)容放到指令所在的地方。把所包含的文件的內(nèi)容放到指令所在的地方。兩種形式:兩種形式:#

3、include 只在指定存放頭文件的目錄下(只在指定存放頭文件的目錄下(IDE的的include子目錄下)查找該文件。子目錄下)查找該文件。#include “filename” 首先在使用文件包含命令的源文件所在目錄下查找該文件;首先在使用文件包含命令的源文件所在目錄下查找該文件; 若未找到,再到指定存放頭文件的目錄下去查找。若未找到,再到指定存放頭文件的目錄下去查找。好處:好處:當許多程序中需要用到一些共同的常量、數(shù)據(jù)等資料時,可以把這些當許多程序中需要用到一些共同的常量、數(shù)據(jù)等資料時,可以把這些共同的東西寫在以共同的東西寫在以.h作為擴展名的頭文件中;作為擴展名的頭文件中;如果哪個程序需

4、要用時,就可用文件包含命令把它們包含進來,省去如果哪個程序需要用時,就可用文件包含命令把它們包含進來,省去了重復定義的麻煩。了重復定義的麻煩。編譯預處理編譯預處理黃興鼎版權所有黃興鼎版權所有文件包含文件包含#include使用說明:使用說明:一個一個#include命令只能指定一個被包含文件,若有多個文件要包命令只能指定一個被包含文件,若有多個文件要包含,則需要用多個含,則需要用多個#include命令。命令。文件包含允許嵌套,即在一個被包含文件中又可以包含另一個文文件包含允許嵌套,即在一個被包含文件中又可以包含另一個文件。件。文件包含命令通常包含的文件是頭文件,即后綴是文件包含命令通常包含的

5、文件是頭文件,即后綴是.h的文件,也的文件,也可以包含其他的源文件,例如,可包含可以包含其他的源文件,例如,可包含.c文件。文件。使用文件包含命令可使多個源文件合并成一個源程序后進行編譯使用文件包含命令可使多個源文件合并成一個源程序后進行編譯和運行。和運行。編譯預處理編譯預處理不允許用不允許用define宏定義注釋符號宏定義注釋符號/*、*/和和/.黃興鼎版權所有黃興鼎版權所有宏定義宏定義#define用一個標識符來表示一個字符串,稱為用一個標識符來表示一個字符串,稱為“宏宏”。被定義為被定義為“宏宏”的標識符稱為的標識符稱為“宏名宏名”。在編譯預處理時,對程序中所有出現(xiàn)的在編譯預處理時,對程

6、序中所有出現(xiàn)的“宏名宏名”,都用宏,都用宏定義中的字符串去代換,這稱為定義中的字符串去代換,這稱為“宏代換宏代換”或或“宏展開宏展開”。包括:包括:不帶參數(shù)的宏定義不帶參數(shù)的宏定義帶參數(shù)的宏定義帶參數(shù)的宏定義編譯預處理編譯預處理黃興鼎版權所有黃興鼎版權所有宏定義宏定義無參數(shù)的宏定義無參數(shù)的宏定義格式:格式:#define 舉例:舉例:說明:說明:宏定義一般寫在程序的開頭。宏定義一般寫在程序的開頭。宏名的命名規(guī)則同變量名,一般習慣用大寫字母,以便與變量區(qū)宏名的命名規(guī)則同變量名,一般習慣用大寫字母,以便與變量區(qū)別,但也允許用小寫字母。宏名的前后應有空格,以便準確地辨別,但也允許用小寫字母。宏名的前

7、后應有空格,以便準確地辨認宏名。認宏名。宏定義必須寫在函數(shù)之外,宏名的有效范圍是從宏定義開始到本宏定義必須寫在函數(shù)之外,宏名的有效范圍是從宏定義開始到本源程序文件結束,或遇到預處理命令源程序文件結束,或遇到預處理命令#undef時止。時止。編譯預處理編譯預處理#define PI 3.14除了定義宏常數(shù)之外,經(jīng)常還用來定義字符串,尤其是路徑:除了定義宏常數(shù)之外,經(jīng)常還用來定義字符串,尤其是路徑:#define ENG_PATH_1 E:Englishlisten_to_thislisten_to_this_3注意字符串不要加注意字符串不要加“ ”。黃興鼎版權所有黃興鼎版權所有宏定義宏定義無參數(shù)

8、的宏定義無參數(shù)的宏定義說明:說明:宏定義不但可以定義常量,還可以定義宏定義不但可以定義常量,還可以定義C語句和表達式等。語句和表達式等。宏定義允許嵌套。宏定義允許嵌套。宏代換只是指定字符串替換宏名的簡單替換,不做任何語法檢查。宏代換只是指定字符串替換宏名的簡單替換,不做任何語法檢查。如有錯誤,只能在編譯已被宏展開后的源程序時發(fā)現(xiàn)。如有錯誤,只能在編譯已被宏展開后的源程序時發(fā)現(xiàn)。宏定義是專門用于預處理命令的一個專用名詞,只作字符替換,不宏定義是專門用于預處理命令的一個專用名詞,只作字符替換,不分配內(nèi)存空間。分配內(nèi)存空間。當宏定義在一行中寫不下,需要在下一行繼續(xù)時,只需在最后一個當宏定義在一行中寫

9、不下,需要在下一行繼續(xù)時,只需在最后一個字符后緊接著加一個反斜杠字符后緊接著加一個反斜杠“”。可用宏定義表示數(shù)據(jù)類型,使書寫方便??捎煤甓x表示數(shù)據(jù)類型,使書寫方便。對程序中用雙撇號括起來的字符串內(nèi)的字符,即使與宏名相同,也對程序中用雙撇號括起來的字符串內(nèi)的字符,即使與宏名相同,也不進行置換。不進行置換。編譯預處理編譯預處理#define L 2*pi*r#define S pi*r*rint main() double r=1,pi=3.14;printf(L=%fnS=%fn,L,S); 黃興鼎版權所有黃興鼎版權所有宏定義宏定義有參數(shù)的宏定義有參數(shù)的宏定義格式:格式:#define 宏名宏

10、名(形參表形參表) 字符串字符串舉例:舉例:編譯預處理編譯預處理#define M(a,b) a*b說明:說明:實參個數(shù)與形參個數(shù)相同,但沒有類型要求。實參個數(shù)與形參個數(shù)相同,但沒有類型要求。宏名和形參表之間不能有空格出現(xiàn)。宏名和形參表之間不能有空格出現(xiàn)。/* (cw1202.c) */#include #define M(y) (y)*(y)int main() int a,x; printf(input a number: ); scanf(%d,&a); x=M(a+1); printf(sq=%dn,x); return 0;#define M(y) y*y這兩種情況當輸入這兩種情況當

11、輸入3時兩者時兩者的輸出結果完全不同的輸出結果完全不同,有括號有括號時為時為16,無括號時為無括號時為7。最好。最好別吝嗇括號別吝嗇括號寫成:寫成:#define M(y) ( (y)*(y))就不會出借了就不會出借了注意:有參宏,又稱為宏函數(shù),在被調(diào)用時是以實參代換形參。而不是“值傳送”,注意:在定義時M與括號之間不能有空格。否則變?yōu)榱撕?。字符串?nèi)的形參通常要用括號括起來以避免出錯。字符串內(nèi)的形參通常要用括號括起來以避免出錯。如果如果a=3+1,b=10,則為則為M(a,b) 為:3+1*10,出借了,所以加( )就不借了。 #define M(a,b) (a)*(b)所以表達式和參數(shù)最好都

12、加上括號。黃興鼎版權所有黃興鼎版權所有條件編譯條件編譯編譯預處理編譯預處理#include /* cw1403.c)*/#define R 1#define PI 3.1415926int main() float c,r,s; printf (input a number: ); scanf(%f,&c); #if R r=PI*c*c; printf(area of round is: %fn,r); #else s=c*c; printf(area of square is: %fn,s); #endif return 0;運行結果為:運行結果為:input a number:10314

13、.158997常量表達式的值為真常量表達式的值為真(非非0),則對程序段,則對程序段1 進行編譯,否則對程進行編譯,否則對程序段序段2進行編譯。因進行編譯。因此可以使程序在不同此可以使程序在不同條件下,完成不同的條件下,完成不同的功能。功能。#if#ifdef#ifndef#else#endif指令:指令:目的和作用目的和作用條件編譯是指對源程序中某段程序通過條件來控制是否參加編譯。條件編譯是指對源程序中某段程序通過條件來控制是否參加編譯。根據(jù)條件選取需要的代碼進行編譯,以便生成不同的應用程序,供不同根據(jù)條件選取需要的代碼進行編譯,以便生成不同的應用程序,供不同用戶使用。用戶使用。此外,條件編

14、譯還可以方便程序的逐段調(diào)試,簡化程序調(diào)試工作。此外,條件編譯還可以方便程序的逐段調(diào)試,簡化程序調(diào)試工作。黃興鼎版權所有黃興鼎版權所有#include #define MIN(a,b) (a)(b)?(a):(b) int main() int min; char ch,chs; min=MIN(5,3); ch=MIN(5,3); printf(min=%dn,min); printf(ch=%cn,ch); printf(chs=%sn,MIN(5,3); return 0; /*在在VC+6中為中為3.注意在注意在TC下結果為下結果為5,因為在因為在TC下不能用下不能用這種方法比較大小這種

15、方法比較大小.*/*cw1404.c */注意:定義宏函數(shù)時不能在函數(shù)名與括號間加空格。黃興鼎版權所有黃興鼎版權所有ANSI標準定義的標準定義的C語言預處理指令語言預處理指令預處理名稱預處理名稱意意 義義#define宏定義宏定義#undef撤銷已定義過的宏名撤銷已定義過的宏名#include使編譯程序將另一源文件嵌入到帶有使編譯程序將另一源文件嵌入到帶有#include的源文件中的源文件中#if#if的一般含義是如果的一般含義是如果#if后面的常量表達式為后面的常量表達式為true,則編譯它與,則編譯它與#endif之之間的代碼,否則跳過這些代碼。命令間的代碼,否則跳過這些代碼。命令#end

16、if標識一個標識一個#if塊的結束。塊的結束。#els命令的功能有點象命令的功能有點象C語言中的語言中的else,#else建立另一選擇(在建立另一選擇(在#if失敗的情失敗的情況下)。況下)。#elif命令意義與命令意義與elseif相同,它形成一個相同,它形成一個ifelse-if階梯狀語句,可階梯狀語句,可進行多種編譯選擇。進行多種編譯選擇。#else#elif#endif#ifdef用用#ifdef與與#ifndef命令分別表示命令分別表示“如果有定義如果有定義”及及“如果無定義如果無定義”,是,是條件編譯的另一種方法。條件編譯的另一種方法。#ifndef#line改變當前行數(shù)和文件名

17、稱,它們是在編譯程序中預先定義的標識符命令改變當前行數(shù)和文件名稱,它們是在編譯程序中預先定義的標識符命令的基本形式如下:的基本形式如下:#line numberfilename#error編譯程序時編譯程序時,只要遇到只要遇到#error就會生成一個編譯錯誤提示就會生成一個編譯錯誤提示,并停止編譯并停止編譯#pragma為實現(xiàn)時定義的命令,它允許向編譯程序傳送各種指令例如,編譯程序為實現(xiàn)時定義的命令,它允許向編譯程序傳送各種指令例如,編譯程序可能有一種選擇,它支持對程序執(zhí)行的跟蹤??捎每赡苡幸环N選擇,它支持對程序執(zhí)行的跟蹤。可用#pragma語句指定一語句指定一個跟蹤選擇。個跟蹤選擇。黃興鼎版

18、權所有黃興鼎版權所有另外另外ANSI標準標準C還定義了如下幾個宏:還定義了如下幾個宏:_LINE_ 表示正在編譯的文件的行號表示正在編譯的文件的行號_FILE_ 表示正在編譯的文件的名字表示正在編譯的文件的名字_DATE_ 表示編譯時刻的日期字符串,如:表示編譯時刻的日期字符串,如:25Dec2007_TIME_表示編譯時刻的時間字符串,如:表示編譯時刻的時間字符串,如:12:30:55_STDC_判斷該文件是不是定義成標準判斷該文件是不是定義成標準C程序程序如果編譯器不是標準的,則可能僅支持以上宏的一部分,或根本如果編譯器不是標準的,則可能僅支持以上宏的一部分,或根本不支持。當然編譯器也有可

19、能還提供其它預定義的宏名。注意:不支持。當然編譯器也有可能還提供其它預定義的宏名。注意:宏名的書寫由標識符與兩邊各二條下劃線構成。宏名的書寫由標識符與兩邊各二條下劃線構成。黃興鼎版權所有黃興鼎版權所有學生成績排序實驗報告綜合例學生成績排序實驗報告綜合例#include stdio.h#include stdlib.h#define N 5 /定義符號常量定義符號常量#define P printftypedef struct student /定義結構體定義結構體int rank; /序號序號char number10; /學學號號int score3; /用數(shù)組存儲數(shù)學、英語、計算機基礎的分

20、數(shù)用數(shù)組存儲數(shù)學、英語、計算機基礎的分數(shù)int sum; /總分總分float average; /平均分平均分 student; /定義結構體變量定義結構體變量student stu100; /定義結構體數(shù)組定義結構體數(shù)組黃興鼎版權所有黃興鼎版權所有void pr() /定義輸出分隔線函數(shù)定義輸出分隔線函數(shù) puts(+n); /*可通過符號常量或者循環(huán)產(chǎn)生可通過符號常量或者循環(huán)產(chǎn)生(見以前各章見以前各章),符號也可以是任何符號符號也可以是任何符號*/void sum_and_average(student stu, sum_and_average(student stu,int num)

21、num) /計算總分和平均分計算總分和平均分 int i,j i,j; ;for(i=0;inum;i(i=0;inum;i+)+) stui.sumstui.sum=0;=0;stui.averagestui.average=0;=0;for(j(j=0;j3;j+)=0;j3;j+) stui.sum+=stui.scorej stui.sum+=stui.scorej; ; /求總分求總分stui.averagestui.average=(float)stui.sum/3;=(float)stui.sum/3; /求平均分求平均分 黃興鼎版權所有黃興鼎版權所有void sort( sor

22、t(typedef student stu, student stu,int num) num) /定義排序函數(shù)定義排序函數(shù) int i,j i,j; ;student stu1; student stu1; for(i(i=0; i=num-1; i+)=0; i=num-1; i+) for(j(j=1; j=num-i; j+) =1; j=num-i; j+) /從高分到低分排序從高分到低分排序 if(stuj-1.sumstuj.sum(stuj-1.sumstuj.sum) ) /比較排序比較排序 stu1=stuj-1;stuj-1=stuj;stuj=stu1; stu1=stuj-1;stuj-1=stuj;stuj=stu1; void Pri (typedef Student stu) /定義輸出函數(shù)定義輸出函數(shù) int i; pr();P(序號序號t學號學號t數(shù)學數(shù)學t英語英語t計算機基礎計算機基礎t總分總分t平均分平均分n);for(i=0;iN;i(i=0;iN;i+) P(%3dt%st%2dt%2dt%5dtt%2dt%.1fn,i+1,stui.number, stui.score0,stui.score1,stui.score2,stui.sum,stui.average); pr();黃興鼎版權所有黃興鼎版權所有int main() in

溫馨提示

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

評論

0/150

提交評論