項目五用函數(shù)實現(xiàn)學(xué)生成績管理系統(tǒng)_第1頁
項目五用函數(shù)實現(xiàn)學(xué)生成績管理系統(tǒng)_第2頁
項目五用函數(shù)實現(xiàn)學(xué)生成績管理系統(tǒng)_第3頁
項目五用函數(shù)實現(xiàn)學(xué)生成績管理系統(tǒng)_第4頁
項目五用函數(shù)實現(xiàn)學(xué)生成績管理系統(tǒng)_第5頁
已閱讀5頁,還剩67頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

項目五用函數(shù)實現(xiàn)學(xué)生成績管理系統(tǒng)-項目五用函數(shù)實現(xiàn)學(xué)生成績管理系統(tǒng)-項目五用函數(shù)實現(xiàn)學(xué)生成績管理系統(tǒng)-項目要點:函數(shù)的概念函數(shù)的定義和調(diào)用函數(shù)調(diào)用時參數(shù)的傳遞編譯預(yù)處理學(xué)習(xí)目標(biāo):熟知函數(shù)的定義和調(diào)用熟練編寫和調(diào)用函數(shù)掌握函數(shù)的嵌套調(diào)用和遞歸調(diào)用掌握宏定義及條件編譯的運用項目五用函數(shù)實現(xiàn)學(xué)生成績管理系統(tǒng)工作任務(wù)導(dǎo)入工作任務(wù)

C語言提倡使用“模塊化設(shè)計思想”?!澳K化設(shè)計思想”就是將一個較復(fù)雜的大問題分解成一個個的子問題,把每個子問題都看成是一個模塊,編寫程序的重心就落在如何實現(xiàn)這些模塊上,這樣就把大問題化小,復(fù)雜的問題化簡單了。本項目就是采用“模塊化設(shè)計思想”,使用函數(shù)來實現(xiàn)學(xué)生成績管理系統(tǒng)。學(xué)生成績管理系統(tǒng)錄入學(xué)生成績輸出學(xué)生成績查詢學(xué)生成績計算總分和平均分退出輸出學(xué)生成績單

本項目在項目四的基礎(chǔ)上對功能模塊重新進行了設(shè)計,處理班級多名學(xué)生多門課程的成績。功能模塊圖右圖所示。工作任務(wù)導(dǎo)入引導(dǎo)問題(1)項目功能較多,如何將相對獨立的功能單獨實現(xiàn)?(2)如何使用已經(jīng)獨立實現(xiàn)的功能塊?(3)保存數(shù)據(jù)的各類變量的作用域是什么?本項目由3個任務(wù)組成。任務(wù)1認識函數(shù),熟悉函數(shù)的定義和調(diào)用;任務(wù)2熟悉函數(shù)的嵌套調(diào)用和遞歸調(diào)用;任務(wù)3用函數(shù)實現(xiàn)學(xué)生成績管理系統(tǒng)。任務(wù)分析:某班有50名學(xué)生,參加3門課程的期末考試,用函數(shù)實現(xiàn)以下功能:①統(tǒng)計1門課程的總分及平均分。②統(tǒng)計多門課程的總分和平均分。③設(shè)計界面,輸出分隔線。通過任務(wù)1,熟悉函數(shù)的定義和調(diào)用方法,實現(xiàn)統(tǒng)計1門課程的總分及平均分的功能。任務(wù)1認識函數(shù)

定義3個函數(shù):函數(shù)1實現(xiàn)輸出一條線,函數(shù)2實現(xiàn)求1門課程總分和平均分的功能,主函數(shù)調(diào)用前兩個函數(shù)來完成任務(wù)。解決方法:可參考程序見書本P.1275.1.1使用函數(shù)實現(xiàn)學(xué)生1門課程的成績管理函數(shù)的定義

函數(shù)可以看作是一個可以執(zhí)行特定功能的“黑匣子”,當(dāng)我們給定輸入時,它就會給出正確的輸出,內(nèi)部程序是怎么執(zhí)行的不必知道。只有當(dāng)我們編寫一個函數(shù)時才需要熟悉內(nèi)部是怎么實現(xiàn)的。在一個C語言程序中,除了必須有main()函數(shù)外,還要經(jīng)常使用一些其他函數(shù),這些函數(shù)通常稱為子函數(shù),子函數(shù)由用戶自己命名,一般完成某種特定的子功能。函數(shù)定義的一般形式:函數(shù)類型函數(shù)名([形式參數(shù)表]){[函數(shù)體]

}5.1.2函數(shù)的定義和調(diào)用函數(shù)的調(diào)用

1、函數(shù)調(diào)用形式調(diào)用函數(shù)的一般形式如下:函數(shù)名([實際參數(shù)列表]);

其中,實際參數(shù)(簡稱實參)是有確定值的變量或表達式,若有多個參數(shù),各參數(shù)間需要用逗號分開。說明:(1)在實參表中,實參的個數(shù)及順序必須和形參的個數(shù)與順序相同,實參的數(shù)據(jù)類型必須和對應(yīng)的形參數(shù)據(jù)類型相同。(2)若為無參數(shù)調(diào)用,則函數(shù)名后的括號不省略。(3)函數(shù)間可以互相調(diào)用,但不能調(diào)用main()函數(shù)。5.1.2函數(shù)的定義和調(diào)用2、函數(shù)調(diào)用的方式按函數(shù)在程序中出現(xiàn)的位置分為以下三種調(diào)用方式:(1)函數(shù)語句:把函數(shù)調(diào)用作為一個語句,即“函數(shù)名([實參表]);”。如printStar();,執(zhí)行該語句時,調(diào)用函數(shù)printStar(),執(zhí)行其功能。這時不要求函數(shù)帶返回值,只要求函數(shù)完成一定的操作。(2)函數(shù)表達式:函數(shù)出現(xiàn)在一個表達式中,要求函數(shù)帶回一個確定的值以參加表達式的運算。如ms=sum(a,b)/2.0;,執(zhí)行該語句時,調(diào)用sum函數(shù),并返回運算值賦值給ms。(3)函數(shù)參數(shù):函數(shù)調(diào)用作為一個函數(shù)的實參。如result=max(a,max(b,c));。5.1.2函數(shù)的定義和調(diào)用問題5.2無參函數(shù)的定義和調(diào)用。#include<stdio.h>voidprintStar(){printf("********************\n");}voidprintMessage(){printf("ThisisaCprogram!\n");}main(){printStar();printMessage();printStar();}【說明】程序中除了主函數(shù)main()之外,還有兩個函數(shù),分別是printStar()函數(shù)和printMessage()函數(shù)。printStar和printMessage分別是兩個函數(shù)的函數(shù)名,并且函數(shù)名后括號中無參數(shù)。練一練編寫函數(shù)實現(xiàn)在屏幕上輸出一條線,并在主函數(shù)中調(diào)用輸出兩條線。問題5.3有參函數(shù)的定義和調(diào)用。#include<stdio.h> intsum(intx,inty){intz; z=x+y; return(z);}main(){ inta,b;floatavg; printf("Inputtwonumbers:"); scanf("%d%d",&a,&b);avg=sum(a,b)/2.0;printf("Theaverageis%f\n",avg);}【說明】

本例實現(xiàn)了從鍵盤輸入兩個整數(shù),在顯示器上輸出這兩個數(shù)的平均值,其中求兩個數(shù)的和是通過一個有參數(shù)的函數(shù)實現(xiàn)的。程序運行的結(jié)果是:

Inputtwonumbers:2335Theaverageis29.000000問題5.4輸入3個數(shù),輸出其最大值。#include<stdio.h>intmax(intx,inty){intmx;mx=x>y?x:y;returnmx;}main(){inta,b,c,result;printf("Pleaseinput3integernumbers:\n");scanf("%d%d%d",&a,&b,&c);result=max(a,max(b,c));printf("Themaxof%d、%d、%dis%d\n",a,b,c,result);}【說明】程序中除了主函數(shù)main()之外,還有用于求兩個數(shù)最大值的max函數(shù)。計算3個數(shù)最大值時,調(diào)用函數(shù)max時的實參用“函數(shù)調(diào)用”方式實現(xiàn),語句result=max(a,max(b,c));即為這種調(diào)用方式。練一練編寫一個求1+2+…+n的函數(shù),并在主函數(shù)中調(diào)用,計算出1到100的累加和。問題5.5編寫一個函數(shù)判斷某年是否是閏年,如果是則返回值為1,如果不是則返回值為0,在主函數(shù)中調(diào)用,判斷輸入的年份是否為閏年。#include"stdio.h"intjudgeLeap(intyear){ if((year%4==0&&year%100!=0)||(year%400==0)) return1; else return0;}voidmain()/*主函數(shù)*/{ intyear; printf("請輸入年份:\n"); scanf("%d",&year); if(judgeLeap(year))printf("%disleapyear!\n",year);elseprintf("%disleapnotyear!\n",year);}

函數(shù)原型

在C程序的源文件中,當(dāng)把被調(diào)用函數(shù)的位置放在主調(diào)函數(shù)的前面時,編譯系統(tǒng)不會提示錯誤;但當(dāng)把被調(diào)函數(shù)放在主調(diào)函數(shù)的下方時,有時編譯系統(tǒng)就會提示有錯誤,這是因為在主調(diào)函數(shù)中調(diào)用某函數(shù)之前應(yīng)對該被調(diào)函數(shù)進行聲明。這及使用變量之前要先進行變量聲明是一樣的。在主調(diào)函數(shù)中對被調(diào)函數(shù)作說明也叫“函數(shù)原型”,目的是讓編譯系統(tǒng)對被調(diào)函數(shù)的合法性進行檢查。函數(shù)聲明的一般形式為:

類型說明符被調(diào)函數(shù)名(類型形參,類型形參,…);任務(wù)分析

在任務(wù)1的基礎(chǔ)上,通過任務(wù)2來熟悉函數(shù)的嵌套調(diào)用,實現(xiàn)統(tǒng)計多門課程的總分和平均分的功能。任務(wù)2嵌套調(diào)用和遞歸調(diào)用本任務(wù)設(shè)計4個函數(shù):函數(shù)1實現(xiàn)輸出一條線,函數(shù)2實現(xiàn)求多門課程的總成績,函數(shù)3實現(xiàn)求某課程的平均分,主函數(shù)負責(zé)函數(shù)的調(diào)用。解決方法:可參考程序見書本P.1345.2.1使用函數(shù)實現(xiàn)學(xué)生多門課程的成績管理

所謂嵌套調(diào)用:就是在調(diào)用一個函數(shù)并在執(zhí)行該函數(shù)中,又調(diào)用另一個函數(shù)的情況。問題5.6編寫程序,用于實現(xiàn)求公式。5.2.2函數(shù)的嵌套調(diào)用#include<stdio.h>main(){longfunC(long,long);longfunN(longn);longm,n,c;printf("Pleaseinputtwonumbers(m、n):");scanf("%ld%ld",&m,&n);c=funC(m,n);printf("C(%ld,%ld)=%ld\n",m,n,c);}longfunC(longm,longn){longfunN(long);longa,b,c,cmn;a=funN(m);b=funN(n);c=funN(m-n);cmn=a/(b*c);return(cmn);}longfunN(longn){longi,result=1;for(i=1;i<=n;i++)result*=i;return(result);}【說明】算法分析:求數(shù)的階乘由函數(shù)funN()來實現(xiàn),求組合數(shù)Cnm用函數(shù)funC()來實現(xiàn)。主函數(shù)main()調(diào)用函數(shù)funC(),而函數(shù)funC調(diào)用函數(shù)funN3次,分別計算m!、n!、(m-n)!。計算結(jié)果返回給主函數(shù)進行輸出。m和n由鍵盤輸入。當(dāng)從鍵盤輸入數(shù)值10和4,程序執(zhí)行結(jié)果如下:

Pleaseinputtwonumbers(m、n):104C(10,4)=210函數(shù)嵌套調(diào)用示意圖練一練用函數(shù)的嵌套調(diào)用實現(xiàn)求|x|*2+1的值。在調(diào)用一個函數(shù)的過程中又出現(xiàn)直接或間接地調(diào)用該函數(shù)本身,稱為函數(shù)的遞歸調(diào)用。C語言允許函數(shù)遞歸調(diào)用,函數(shù)遞歸調(diào)用可分為直接遞歸調(diào)用和間接遞歸調(diào)用。函數(shù)的遞歸調(diào)用示意圖如下頁所示。5.2.3函數(shù)的遞歸調(diào)用函數(shù)遞歸調(diào)用示意圖問題5.7用遞歸調(diào)用編寫計算階乘n!的函數(shù)fact()【程序代碼】#include<stdio.h>longfact(intn){longrst;if(n<0)printf("n<0,dataerror!\n");elseif(n==0||n==1)rst=1;elserst=n*fact(n-1);return(rst);}main(){intn;longresult;printf("Pleaseinputanintegernumber(n):");scanf("%d",&n);result=fact(n);printf("%d!=%ld\n",n,result);getch();}【說明】根據(jù)階乘的計算公式:n!=n*(n-1)!,為了計算n!,需要調(diào)用計算階乘的函數(shù)fact(n),它又要計算(n-1)!,此時又需要再調(diào)用fact(n-1),依次類推,于是形成遞歸調(diào)用。這個調(diào)用過程一直繼續(xù)到計算1!為止。下面以求5!為例分析本程序的遞歸調(diào)用和返回的過程

問題5.8用遞歸方法編寫一個程序,求兩個正整數(shù)的最大公因數(shù)。【程序代碼】#include<stdio.h>intgcd(intx,inty){if(y<=x&&x%y==0)returny;elseif(y>x)returngcd(y,x);elsereturngcd(y,x%y);}main(){inta,b;printf("Pleaseinputtwointegers:");scanf("%d%d",&a,&b);printf("Thegcdis%d\n",gcd(a,b));}練一練有5個人坐在一起,問第5個人多少歲,他說比第4個人大2歲。問第4個人多少歲,他說比第3個人大2歲。問第3個人多少歲,他說比第2個人大2歲。問第2個人多少歲,他說比第1個人大2歲。問第1個人多少歲,他說是10歲。請用遞歸函數(shù)求出第5個人多少歲。任務(wù)分析

使用函數(shù),完善學(xué)生成績管理系統(tǒng)。本任務(wù)中將系統(tǒng)分解成6個功能模塊,每個模塊用函數(shù)來實現(xiàn)。函數(shù)1實現(xiàn)多名學(xué)生3門課程成績的輸入;函數(shù)2實現(xiàn)學(xué)生成績的輸出;函數(shù)3實現(xiàn)學(xué)生成績的查詢;函數(shù)4實現(xiàn)計算每位學(xué)生的總分和平均分;函數(shù)5實現(xiàn)按照總分由大到小的順序輸出學(xué)生的成績;主函數(shù)總負責(zé)調(diào)用這些函數(shù)。要實現(xiàn)以上功能,必須了解函數(shù)參數(shù)的特點。任務(wù)3用函數(shù)實現(xiàn)學(xué)生成績管理系統(tǒng)

使用函數(shù),完善學(xué)生成績管理系統(tǒng)。由于學(xué)生的成績信息存放在二維數(shù)組中,所以采用數(shù)組名作為函數(shù)的參數(shù)。在本系統(tǒng)設(shè)計5個函數(shù)。解決方法:可參考程序見書本P.1395.3.1使用函數(shù)完善學(xué)生成績管理系統(tǒng)

值調(diào)用

值調(diào)用方法是把實參的值傳遞給形參,即調(diào)用函數(shù)向被調(diào)用函數(shù)傳遞的參數(shù)是變量本身的值。形參在調(diào)用前和調(diào)用后都是不存在的,只有函數(shù)被調(diào)用時形參才被分配相應(yīng)的內(nèi)存單元,調(diào)用結(jié)束立即釋放。實參及形參即使是同名的變量,它們都占用不同的內(nèi)存單元,互不影響,這時形參值的變化將不影響實參的值。5.3.2函數(shù)的值調(diào)用和引用調(diào)用問題5.9用值調(diào)用函數(shù)實現(xiàn)兩個數(shù)的交換?!境绦虼a】#include<stdio.h>voidswap(intx,inty){intt;t=x;x=y;y=t;printf("%d\t%d\n",x,y);}main(){inta,b;printf("Pleaseinputtwointegernumbers(a,b):");scanf("%d%d",&a,&b);swap(a,b);}練一練認真分析下列問題,如按這些問題修改程序,題目5.9的運行結(jié)果將會怎樣?(1)swap()函數(shù)中的輸出語句移到主函數(shù)的swap()后面。(2)在主函數(shù)的swap()后面添加一條語句:

printf(“%d\t,%d\n”,a,b);注意:在C語言中,如果實參變量對形式參數(shù)的數(shù)據(jù)傳遞是“傳值”,則是單向傳遞,只能由實參傳給形參,而不能由形參傳給實參。引用調(diào)用

引用調(diào)用是在調(diào)用時把實參的地址傳遞給形參,使用地址去訪問實參,通常簡稱“傳址”。此時主調(diào)函數(shù)向被調(diào)用函數(shù)傳遞的參數(shù)不是變量本身,而是變量的地址,當(dāng)被調(diào)函數(shù)中向相應(yīng)地址的單元寫入不同的數(shù)值之后,也就改變了調(diào)用函數(shù)中相應(yīng)變量(參數(shù))的值,從而達到了返回多個變量值的目的,這種調(diào)用方式通常用數(shù)組名或指針作為函數(shù)參數(shù)。5.3.2函數(shù)的值調(diào)用和引用調(diào)用簡單變量作函數(shù)參數(shù)當(dāng)實參是簡單變量時,就是簡單變量作為函數(shù)參數(shù)的情況。前面所舉實例均采用這種簡單變量作為函數(shù)參數(shù)的方法。數(shù)組元素作函數(shù)參數(shù)由于實參可以是表達式形式,表達式中可以包含數(shù)組元素,因此數(shù)組元素當(dāng)然可以作為函數(shù)的實際參數(shù),及用簡單變量作實參一樣,是單向傳遞,即“傳值”方式。5.3.3函數(shù)的參數(shù)問題5.10編寫一個程序,輸出給定的成績數(shù)組中不及格(成績低于60)的人數(shù)。#include<stdio.h>#defineN10intfun(intx){return(x<60?1:0);}main(){inta[N],i,num=0;printf("Pleaseinput%dnumbers:",N);for(i=0;i<N;i++) {scanf("%d",&a[i]);num+=fun(a[i]); }printf("Thenumberofnopassis:%d\n",num);}

【說明】分析:設(shè)計一個函數(shù)fun(x),當(dāng)x<60時返回1,否則返回0。在main()函數(shù)中,掃描整個成績數(shù)組a,對每個數(shù)組元素調(diào)用fun()函數(shù),并累加返回的數(shù)值。數(shù)組名作函數(shù)參數(shù)當(dāng)數(shù)組名作為形參時,其實參也應(yīng)用數(shù)組名(或指針變量,參見第6章),且實參數(shù)組必須及形參數(shù)組類型一致。當(dāng)函數(shù)參數(shù)是數(shù)組時,此時傳遞的是數(shù)組的地址(首地址),而不是將整個數(shù)組元素都傳遞到函數(shù)中去,使得形參數(shù)組與實參數(shù)組共占同一段內(nèi)存單元,這就是“傳址”方式。5.3.3函數(shù)的參數(shù)問題5.11用選擇法對數(shù)組中5個整數(shù)按由小到大排序。#include<stdio.h>voidsort(intarr[5]){inti,j,k,t;for(i=0;i<5-1;i++){k=i;for(j=i+1;j<5;j++)if(arr[j]<arr[k])k=j;t=arr[k];arr[k]=arr[i];arr[i]=t;}}main(){inta[5],i;printf("Pleaseinputthearray:\n");for(i=0;i<5;i++)scanf("%d",&a[i]);sort(a);printf("thesortedarray:\n");for(i=0;i<5;i++)printf("%d",a[i]);printf("\n");}說明:實參數(shù)組和形參數(shù)組大小可以一致,也可以不一致。C編譯系統(tǒng)對形參數(shù)組大小不做語法檢查,只是將實參數(shù)組的首地址傳遞給形參數(shù)組。另外,形參數(shù)組也可以不指定大小,在定義數(shù)組時在數(shù)組后面跟一對空的方括號。如題目5.11中,sort()函數(shù)可以定義為:voidsort(intarr[])或voidsort(intarr[],intn)不僅一維數(shù)組名可以作為函數(shù)參數(shù),多維數(shù)組名也可作為函數(shù)參數(shù),其參數(shù)傳遞都是“地址傳遞”。對于利用多維數(shù)組作為函數(shù)參數(shù)來說,在被調(diào)用函數(shù)中對形參數(shù)組定義時可以指定每一維的大小,也可以省略第一維的大小說明,且二者等價,但是不能把第二維以及其他高維的大小說明省略。

練一練用函數(shù)實現(xiàn)數(shù)組元素的逆序。5.4.1變量的作用域形參變量只在被調(diào)用期間才分配內(nèi)存單元,調(diào)用結(jié)束就立即釋放內(nèi)存。這一點表明形參變量只有在函數(shù)內(nèi)部才是有效的,離開該函數(shù)就不能再使用了。這種變量有效性的范圍稱變量的作用域。不僅對于形參變量,C語言中所有的變量都有自己的作用域。變量說明的方式不同,其作用域也不同。C語言中的變量,按作用域范圍可分為兩種,即局部變量和全局變量。任務(wù)4任務(wù)拓展一、局部變量局部變量也稱為內(nèi)部變量。局部變量定義在函數(shù)的內(nèi)部。其作用域僅限于函數(shù)內(nèi),離開該函數(shù)后,該變量的作用便消失,無法使用該變量。問題5.13分析下面程序的運行結(jié)果

voidf(){intk=5;printf("f:k=%d\n",k);}main(){inti,k;k=3;f();for(i=1;i<3;i++) {intk=8+i; printf("main->for:k=%d\n",k); }printf("main:k=%d\n",k);}二、全局變量

全局變量也稱為外部變量,它是在函數(shù)外部定義的變量。它不屬于哪一個函數(shù),它屬于一個源程序文件。其作用域是從定義變量的位置開始到當(dāng)前源文件結(jié)束。inta,b;/*外部變量作用范圍是從這里開始到文件結(jié)束*/voidf1()/*函數(shù)f1*/{……}floatx,y;/*外部變量作用范圍是從這里開始到文件結(jié)束*/intf2()/*函數(shù)f2*/{……}main()/*主函數(shù)*/{……}

從上例可以看出a,b,x,y都是在函數(shù)外部定義的外部變量,都是全局變量。但x,y定義在函數(shù)f1之后,而在f1內(nèi)又沒有對x,y的說明,所以它們在f1內(nèi)無效。a,b定義在源程序最前面,因此在f1,f2及main內(nèi)不加說明也可使用。

5.4.2編譯預(yù)處理

C語言提供的預(yù)處理功能主要有以下3種:宏定義、文件包含和條件編譯。編譯預(yù)處理命令不屬于C語句的范疇。為表示區(qū)別,所有的編譯預(yù)處理命令均以#符號開頭,各占用一個單獨的書寫行,末尾不用分號作結(jié)束符。如果一行書寫不下,可用反斜線(\)和回車鍵結(jié)束,然后在下一行繼續(xù)書寫。它們可以出現(xiàn)在程序的任何位置,作用域是自出現(xiàn)的地方開始到源程序的末尾。一、宏定義

宏定義是指用一個指定的宏名(標(biāo)識符)來代表一個字符串。在對源文件進行預(yù)處理時,用宏定義的字符串來代替每次出現(xiàn)的宏名。另外,宏名不僅可以代表字符串,還可以接收參數(shù)以擴展宏的使用。因此,宏可分為不帶參數(shù)的宏和帶參數(shù)的宏兩種。1、不帶參數(shù)的宏定義是用一個指定的標(biāo)識符(即宏名)來代表一個字符串,其定義的一般形式為:#define標(biāo)識符字符串其中,標(biāo)識符是用戶定義的,遵循C語言標(biāo)識符的命名規(guī)則,要求它及后面的字符串之間用空格符分隔;字符串不能用雙引號界定。注意:宏定義不是語句,不能在末尾添加分號“;”。#defineNUM50#defineTRUE1#defineFALSE0#defineNLprintf(“\n”)#defineLEN100;/*因添加“;”而出錯,則LEN代表“100;”這個字符串*/問題5.14定義不帶參數(shù)的宏?!境绦虼a】#definePI3.14159/*定義無參數(shù)宏P(guān)I*/#definePRprintf/*定義無參數(shù)宏P(guān)R*/main(){floats,r;PR(“PleaseInputRadius:”);/*使用宏*/scanf(“%f”,&r);s=PI*r*r;/*使用宏*/PR(“r=%.2f,s=%.2f\n”,r,s);/*使用宏*/}經(jīng)過預(yù)編譯處理后的程序變?yōu)椋簃ain(){floats,r;printf(“PleaseInputRadius:”);scanf(“%f”,&r);s=3.14159*r*r;printf(“r=%.2f,s=%.2f\n”,r,s);}【說明】在預(yù)編譯處理時將宏名替換成字符串的過程稱為宏展開,或稱宏替換。本題中宏P(guān)R用“printf”字符串代替,PI由“3.14159”字符串代替。說明:(1)習(xí)慣上,宏定義名一般用大寫,以區(qū)別一般關(guān)鍵字和其他變量。(2)宏定義不是C語句,不能在最后加上分號作為結(jié)束符。如果加了分號,則在預(yù)編譯處理時連分號一起進行替換。例如:

#definePI3.14159;

s=PI*r*r;經(jīng)過預(yù)處理展開后,語句變?yōu)椋?/p>

s=3.14159;*r*r;顯然是錯誤的。(3)宏名的有效范圍是從定義開始到本源文件結(jié)束。如果想在源文件結(jié)束前終止宏定義的作用域,可以用#undef命令。例如:

#defineW9.8main(){┇W的有效范圍

}#undefW(4)使用宏名代替一個字符串,可以減少程序中重復(fù)書寫某些字符串的工作量,也可以提高程序的可讀性和可維護性,如在問題5.1中,如果要提高PI的精確度,將PI定義成3.1415926時,只需將宏定義中PI的值修改一下,程序中其他地方的PI值將自動同時修改。(5)若在字符串中出現(xiàn)及宏名相同的字符串,系統(tǒng)不認為是宏名,預(yù)處理時也不作宏展開。例如:

#definePI3.14159…printf(“PI=%f”,PI);/*“PI=%f”中的PI不是宏名*/

輸出結(jié)果是:

PI=3.14159(6)在進行宏定義時,可以引用已定義過的宏名,在宏展開時可以層層替換。例如:

#definePI3.14159#defineR12#defineSPI*R*Rprintf(“S=%.2f”,S);

輸出結(jié)果是:

S=452.392、帶參數(shù)的宏定義帶參數(shù)的宏定義除了進行必要的字符串替換外,還可以進行參數(shù)的替換。帶參數(shù)的宏定義的一般形式是:

#define標(biāo)識符(參數(shù)表)字符串其中,參數(shù)表中可以是一個或多個參數(shù);字符串應(yīng)有參數(shù)表中的參數(shù)。例如:定義矩形面積的宏S、a和b是邊長:

#defineS(a,b)a*b/*p定義帶參數(shù)的宏*/area=S(3,2);/*參數(shù)a的值為3,b的值為2*/上式展開為:

area=3*2;問題5.15定義帶參數(shù)的宏。【程序代碼】#definePI3.14159/*定義無參數(shù)的宏P(guān)I*/#defineS(r)PI*r*r/*用帶參數(shù)的宏S(r)表示圓的面積公式*/main(){floata,area;a=3.6;area=S(a);printf(“r=%f\narea=%f\n”,a,area);}【說明】運行結(jié)果:

r=3.600000area=40.715038對于帶參數(shù)的宏的說明:(1)對于帶參數(shù)的宏的展開,只是將語句中的宏名后面括號中的實參字符串代替#define命令行中的形參。(2)為了使宏定義更有通用性且不易出錯,一般將參數(shù)用括號括起來。(3)不能把有參數(shù)宏及函數(shù)相混淆。宏只是字符序列的替換,沒有值的傳送,且宏名、參數(shù)都沒有數(shù)據(jù)類型的概念;函數(shù)要比宏復(fù)雜,有數(shù)據(jù)類型、參數(shù)傳遞等概念。問題5.16分析下面程序的功能。【程序代碼】#defineMAX(a,b)((a)>(b))?(a):(b)main(){intx,y,max;printf("Inputtwonumbers:");scanf("%d%d",&x,&y);max=MAX(x,y);printf("max=%d\n",max);}【說明】本程序的第1行中定義了帶參數(shù)的宏MAX(a,b),同使用函數(shù)相比,宏代碼更簡潔。運行結(jié)果:Inputtwonumbers:1315Max=15練一練運用宏計算矩形的面積和周長。運用宏計算球的表面積。二、文件包含

文件包含是指在一個文件中使用#include預(yù)處理命令將另一個文件的全部內(nèi)容包含進來,而不是直接將源程序重新寫入程序中。文件包含命令的一般形式為:#include“文件名”或者:#include<文件名>上述兩種文件包含形式的區(qū)別在于:(1)使用尖括號(<>):直接到存放C庫函數(shù)頭文件所在的目錄去查找被包含文件,這稱為標(biāo)準(zhǔn)方式。(2)使用雙引號(“”):系統(tǒng)首先到當(dāng)前目錄下查找被包含文件,如果沒找到,再到系統(tǒng)存放C庫函數(shù)頭文件所在的目錄中查找。一般地說,如果為調(diào)用庫函數(shù)而用#include命令來包含相關(guān)頭文件,則用尖括號,以節(jié)省查找時間。如果要包含的是用戶自己編寫的文件,則用(“”),若文件不在當(dāng)前目錄中,雙引號內(nèi)可給出文件路徑。前面已多次用到此命令包含庫函數(shù)的頭文件。例如:

#include<stdio.h>#include<math.h>說明:(1)一個#include命令只能指定一個被包含文件。如果要包含多個文件,則需要用多個#include命令。編譯預(yù)處理時,預(yù)處理程序?qū)⒉檎抑付ǖ谋话募⑵鋸?fù)制到#include命令出現(xiàn)的位置上。(2)文件包含可以嵌套,即被包含文件中又包含另一個文件。例如,在filel.c中包含file2.c,在file2.c中包含file3.c。在filel.c中,這種包含關(guān)系可以表示如下:

#include“file3.c”#include“file2.c”

由于file2.c包含file3.c,所以需要將包含file3.c的預(yù)處理命令放在包含file2.c的預(yù)處理命令前。通過上面的文件包含,filel.c和file2.c都可以用file3.c中的內(nèi)容。在file2.c中不必再用#include“file3.c”。(3)常用在文件頭部的被包含文件,稱為“頭文件”,以.h作為后綴。在頭文件中,除可包含宏定義外,還可包含外部變量定義、結(jié)構(gòu)類型定義等。

問題5.17寫一個判斷素數(shù)的函數(shù),在主函數(shù)中輸入一個整數(shù),輸出該數(shù)是否為素數(shù)的信息。分析:本例中定義prime函數(shù)是有參數(shù)的函數(shù),實參就是需要判斷的數(shù),將其在調(diào)用prime函數(shù)時傳遞給變量number,實現(xiàn)實參和形參的值傳遞。函數(shù)的返回值作

溫馨提示

  • 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)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論