C語言程序設計課件:函數(shù)_第1頁
C語言程序設計課件:函數(shù)_第2頁
C語言程序設計課件:函數(shù)_第3頁
C語言程序設計課件:函數(shù)_第4頁
C語言程序設計課件:函數(shù)_第5頁
已閱讀5頁,還剩43頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

C語言程序設計

函數(shù)8.1函數(shù)定義

8.2函數(shù)參數(shù)和返回值

8.2.1形式參數(shù)和實際參數(shù)

8.2.2函數(shù)返回值

8.3函數(shù)調用

8.3.1調用方式

8.3.2函數(shù)說明

8.3.3函數(shù)嵌套調用

8.3.4函數(shù)遞歸調用

8.4數(shù)組作為函數(shù)參數(shù)

8.5局部變量和全局變量

8.5.1局部變量

8.5.2全局變量

8.6存儲類型

8.6.1auto存儲類型

8.6.2extern存儲類型

8.6.3register存儲類型

8.6.4static存儲類型8.7內部函數(shù)和外部函數(shù)

C語言不僅提供了極為豐富的庫函數(shù)(如TurboC,MSC都提供了三百多個庫函數(shù)),還允許用戶建立自己定義的函數(shù)。用戶編寫一個個相對獨立的函數(shù)模塊算法,然后用調用的方法來使用函數(shù)。例8-1帶參函數(shù)程序main(){inta,b,c;scanf(“%d,%d”,&a,&b);c=fun(a,b);printf(“funis%d”,c);}fun(intx,inty){intz;if(x>y)z=x;elsez=y;return(z);}說明:(1)一個源程序文件由一個或多個函數(shù)組成。一個源程序文件是一個編譯單位,即以源文件為單位進行編譯,而不是以函數(shù)為單位進行編譯。(2)一個C語言程序由一個或多個源程序文件組成。對于較大的程序,一般不希望全放在一個文件中,而是將函數(shù)和其他內容(如預編譯命令)分別放到若干個源文件中,再由若干個源文件組成一個C語言程序。這樣可以分別編寫、分別編譯,提高調試效率。一個源文件可以為多個C語言程序共用。(3)C語言程序的執(zhí)行從main函數(shù)開始,調用其它函數(shù)后流程回到main函數(shù),在main函數(shù)中結束整個程序的運行。(4)所有函數(shù)都是平行的,即在定義函數(shù)時是相互獨立的,一個函數(shù)并不從屬于另一個函數(shù),即函數(shù)不能嵌套定義,但可以相互調用,甚至嵌套調用、遞歸調用(不能調用main函數(shù))。

(5)從用戶使用角度看,函數(shù)有兩種。●標準函數(shù),即庫函數(shù)。這是由系統(tǒng)提供的,用戶無須定義,也不必在程序中作類型說明,只需在程序前包含有該函數(shù)原型的頭文件即可在程序中直接調用?!裼脩糇约憾x的函數(shù),以解決用戶的專門需要。(6)從函數(shù)的形式看,函數(shù)分兩類?!駸o參函數(shù)。在調用無參函數(shù)時,主調函數(shù)并不將數(shù)據(jù)傳送給被調用函數(shù),一般用來執(zhí)行指定的一組操作。無參函數(shù)可以帶回也可以不帶回函數(shù)值,但一般以不帶回函數(shù)值居多?!裼袇⒑瘮?shù)。在調用函數(shù)時,在主調函數(shù)和被調函數(shù)之間有參數(shù)傳遞,也就是說,主調函數(shù)可以將數(shù)據(jù)傳給被調函數(shù)使用,被調用函數(shù)中的數(shù)據(jù)也可以帶回來供主調函數(shù)使用。8.1函數(shù)的定義1.函數(shù)的定義(1)無參函數(shù)的一般形式類型說明符函數(shù)名(){類型說明;語句;}(2)有參函數(shù)的一般形式

類型說明符函數(shù)名(形式參數(shù)表){類型說明;

語句;}voidHello(){printf("Hello,world\n");}intmax(a,b)inta,b;{if(a>b)returna;elsereturnb;}8.2.1形式參數(shù)和實際參數(shù)

函數(shù)的形參和實參具有以下特點:1.形參變量只有在被調用時才分配內存單元,在調用結束時,即刻釋放所分配的內存單元,因此,形參只有在函數(shù)內部有效。函數(shù)調用結束返回主調函數(shù)后則不能再使用該形參變量。2.實參可以是常量、變量、表達式、函數(shù)等,無論實參是何種類型的量,在進行函數(shù)調用時,它們都必須具有確定的值,以便把這些值傳送給形參。3.實參和形參在數(shù)量上、類型上、順序上應嚴格一致,否則會發(fā)生“類型不匹配”的錯誤。4.函數(shù)調用中發(fā)生的數(shù)據(jù)傳送是單向的。即只能把實參的值傳送給形參,而不能把形參的值反向地傳送給實參,因此在函數(shù)調用過程中,形參的值發(fā)生改變,而實參中的值不會變化。8.2函數(shù)參數(shù)和返回值

例8-3求兩整數(shù)中的較大值。#include<stdio.h>intmax(inta,intb);voidmain(){ inta,bmax; printf("輸入兩整數(shù):"); scanf("%d%d",&a,&b); max=max(a,b);/*調用max函數(shù),在表達式中出現(xiàn)*/ printf("\n兩整數(shù)中的較大值是%d\n",max);}intmax(inta,intb)/*求兩整數(shù)中的較大值函數(shù)定義*/{ if(a>b)returna; elsereturnb;}函數(shù)的值是指函數(shù)被調用之后,執(zhí)行函數(shù)體中的程序段所取得的并返回給主調函數(shù)的值,這就是函數(shù)的返回值。說明:(1)函數(shù)的值只能通過return語句返回主調函數(shù)。return語句的一般形式為:

return表達式;

return(表達式);return;該語句的功能是計算表達式的值,并返回給主調函數(shù)。在函數(shù)中允許有多個return語句,但每次調用只能有一個return語句被執(zhí)行,因此只能返回一個函數(shù)值。8.2.2函數(shù)返回值

(2)函數(shù)值得類型。既然函數(shù)可以有返回值,這個值當然應屬于某一個確定的類型,應當在定義函數(shù)時指定函數(shù)值的類型。例如:intmax(inti,inty)charletter(charc1,charc2)floatf(floatx)doublemin(doublex,doubley)C語言還規(guī)定,凡不加類型聲明的函數(shù),一律自動按整型處理。(3)函數(shù)值的類型和函數(shù)定義中函數(shù)的類型應保持一致。如果兩者不一致,則以函數(shù)類型為準,自動進行類型轉換。(4)不返回函數(shù)值的函數(shù),可以明確定義為“空類型”,類型說明符為“void”。voids(intn){…}一旦函數(shù)被定義為空類型后,就不能在主調函數(shù)中使用被調函數(shù)的函數(shù)值了。例如,在定義s為空類型后,在主函數(shù)中寫下述語句sum=s(n);就是錯誤的。為了使程序有良好的可讀性并減少出錯,不要求返回值的函數(shù)都應定義為空類型。函數(shù)調用的一般形式為

被調用函數(shù)名([參數(shù)表達式1,參數(shù)表達式2,…,參數(shù)表達式n]);其中,參數(shù)前不加數(shù)據(jù)類型說明,參數(shù)表達式可以是常量、變量或表達式。各個參數(shù)表達式之間用逗號分割。參數(shù)表示式的個數(shù)與該函數(shù)定義時形式參數(shù)的個數(shù)、數(shù)據(jù)類型都應該匹配,否則會出現(xiàn)預料不到的結果。如果被調用函數(shù)是無參函數(shù),即[]中沒有內容時,函數(shù)名后面的括號不要省略。使用C語言的庫函數(shù)就是函數(shù)簡單調用的方法。例如:

main()

{

printf(“******\n”);

}8.3函數(shù)調用

8.3.1調用方式

(1)函數(shù)表達式

函數(shù)作為表達式中的一項出現(xiàn)在表達式中,以函數(shù)返回值參與表達式的運算。這種方式要求函數(shù)有返回值。例如:

z=max(x,y)*8;其中,函數(shù)max是賦值表達式的一部分,它的值乘以8后在賦予變量z(2)函數(shù)語句函數(shù)調用的一般形式加上分號即構成函數(shù)語句。例如:

printf(“%d”,m);

max(x,y);等都是以函數(shù)語句的方式調用函數(shù)。(3)函數(shù)實參函數(shù)作為另一個函數(shù)調用的實際參數(shù)出現(xiàn)。這種情況是把該函數(shù)的返回值作為實參傳遞給調用函數(shù),因此要求該函數(shù)必須有返回值。例如:

printf(“%d”,max(m,n));上述語句是把max函數(shù)的返回值又作為printf函數(shù)的實參來使用。對被調函數(shù)的說明也有兩種格式,一種為傳統(tǒng)格式。其格式為:類型說明符被調函數(shù)名();這種格式只給出函數(shù)返回值的類型,被調函數(shù)名及一個空括號。這種格式由于在括號中沒有任何參數(shù)信息,因此不便于編譯系統(tǒng)進行錯誤檢查,容易發(fā)生錯誤。另一種為現(xiàn)代格式,其一般形式為:類型說明符被調函數(shù)名(類型形參,類型形參…);

或為:類型說明符被調函數(shù)名(類型,類型…);

現(xiàn)代格式的括號內給出了形參的類型和形參名,或只給出形參類型。這便于編譯系統(tǒng)進行檢錯,以防止可能出現(xiàn)的錯誤。max函數(shù)的說明若用傳統(tǒng)格式可寫為:intmax();用現(xiàn)代格式可寫為:intmax(inta,intb);或寫為:intmax(int,int);8.3.2函數(shù)說明

注意:(1)被調用的函數(shù)必須是已經(jīng)存在的函數(shù)(是庫函數(shù)或用戶自己定義的函數(shù))(2)在調用系統(tǒng)函數(shù)時,需要用包含命令#include“頭文件名.h”將定義系統(tǒng)函數(shù)的庫文件包含在本程序中,有關包含命令的相關知識在后面章節(jié)中詳細介紹。(3)如果調用函數(shù)和主函數(shù)在一個編譯單元中,則在書寫順序上被調用函數(shù)比主函數(shù)先出現(xiàn);或者被調用函數(shù)雖然在主函數(shù)之后出現(xiàn),而被調用函數(shù)的數(shù)據(jù)類型是整型或字符型,可以不對被調函數(shù)加以說明,除了上述兩種情況以外,都要對被調用函數(shù)加以說明。函數(shù)的原型說明8.3.3函數(shù)嵌套調用

例8-5用以下近似公式編程計算ex的值,ex=1+x+x2/2!+x3/3!+…(前20項的和)。#include<stdio.h>floatf2(intn) {if(n==1)return1;elsereturn(f2(n-1)*n);}floatf1(intx,intn){inti;floatj=1;for(i=1;i<=n;i++)j=j*x;returnj;}voidmain(){floatexp=1.0;intn,x;printf(“Inputanumber:”);scanf(“%d”,&x);printf(“%\n”,x);exp=exp+x;for(n=2;n<=19;n++)exp=exp+f1(x,n)/f2(n);printf(“\nTheisexp(%d)=%8.4f\n”,x,exp);}一個函數(shù)在它的函數(shù)體內調用它自身稱為遞歸調用。這種特殊的函數(shù)稱為遞歸函數(shù)。遞歸調用有兩種:直接遞歸調用和間接遞歸調用。8.3.4函數(shù)遞歸調用

例8-6用遞歸法計算n!。#include<stdio.h>longff(intn){longf;if(n<0)printf("n<0,inputerror");elseif(n==0||n==1)f=1;elsef=ff(n-1)*n;return(f);}voidmain(){intn;longy;printf("\ninputainteagernumber:\n");scanf("%d",&n);y=ff(n);printf("%d!=%ld",n,y);}例8-7Hanoi塔問題。一塊板上有三根針,A,B,C。A針上套有64個大小不等的圓盤,大的在下,小的在上。要把這64個圓盤從A針移動C針上,每次只能移動一個圓盤,移動可以借助B針進行。但在任何時候,任何針上的圓盤都必須保持大盤在下,小盤在上。求移動的步驟:#include<stdio.h>move(intn,intx,inty,intz){if(n==1)printf("%c-->%c\n",x,z);else{move(n-1,x,z,y);printf("%c-->%c\n",x,z);move(n-1,y,x,z);}}voidmain(){inth;printf("\ninputnumber:\n");scanf("%d",&h);printf("thesteptomoving%2ddiskes:\n",h);move(h,'a','b','c');}

數(shù)組名能作為函數(shù)的形參,但不能作為函數(shù)的返回值類型。數(shù)組名作為實參時是傳遞數(shù)組首地址。形參數(shù)組實質是一個指針變量,占2字節(jié),存實參數(shù)組的首地址。傳址(傳地址值)是C函數(shù)參數(shù)傳遞的第二種方法,效率高,用途廣;但難度比傳值(傳數(shù)據(jù)值)大。8.4數(shù)組作為函數(shù)參數(shù)

2.數(shù)組名作為函數(shù)參數(shù)例8-8一維數(shù)組的數(shù)組元素值減2。#include<stdio.h>#defineN5 voidadd1(intx[],intn);voidmain(){inta[N]={6,7,8,9,10},i;printf("數(shù)組A[%d]:\n",N);for(i=0;i<N;i++)printf("a[%d]:%x%5d\n",i,&a[i],a[i]);add1(a,N);printf("\n數(shù)組A[%d:\n",N);for(i=0;i<N;i++)printf("a[%d]:%x%5d\n",i,&a[i],a[i]);}voidadd1(intx[],intn) {inti;printf("x中的值(地址):%x\n",x);printf("數(shù)組x[%d]:\n",n);for(i=0;i<n;i++)printf("x[%d]:%x%5d\n",i,&x[i],x[i]);for(i=0;i<n;i++) x[i]=x[i]-2;}例8-9有一個一維數(shù)組score,內放10個學生成績,求平均成績。#include<stdio.h>floataverage(floatarray[10]);voidmain(){floatscore[10],aver;inti;printf(“input10scores:\n”);for(i=0;i<10;i++)scanf(“%f”,&score[i]);printf(“\n”);aver=average(score);printf(“averagescoreis%5.2f”,aver);}floataverage(floatarray[10]){inti;floataver,sum=array[0];for(i=1;i<10;i++)sum=sum+array[i];aver=sum/10;return(aver);}局部變量也稱為內部變量。局部變量是在函數(shù)內作定義說明的。它只在該函數(shù)范圍內有效。也就是說,只有在包含變量說明的函數(shù)內部,才能使用被說明的變量,在此函數(shù)之外就不能使用這些變量了,離開該函數(shù)后再使用這種變量是非法的。例如:intf1(inta)/*函數(shù)f1*/{intb,c;……}a、b、c作用域。intf2(intx)/*函數(shù)f2*/{inty,z;}x、y、z作用域。voidmain(){intm,n;}m、n作用域。8.5局部變量和全局變量

8.5.1局部變量

關于局部變量的作用域還要說明以下幾點:(1)主函數(shù)main()中定義的變量,也只能在主函數(shù)中使用,其它函數(shù)不能使用。同時,主函數(shù)中也不能使用其它函數(shù)中定義的變量。因為主函數(shù)也是一個函數(shù),與其它函數(shù)是平行關系。這一點是與其它語言不同的,應予以注意。(2)形參變量也是內部變量,屬于被調用函數(shù);實參變量,則是調用函數(shù)的內部變量。(3)允許在不同的函數(shù)中使用相同的變量名,它們代表不同的對象,分配不同的單元,互不干擾,也不會發(fā)生混淆。(4)在復合語句中也可定義變量,其作用域只在復合語句范圍內。第8章函數(shù)8.5局部變量和全局變量例8-10定義變量的作用域。inta,b;/*外部變量*/voidf1()/*函數(shù)f1*/{……}floatx,y;/*外部變量*/intfz()/*函數(shù)fz*/{……}voidmain()/*主函數(shù)*/{……}/*全局變量x、y作用域,全局變量a、b作用域*/8.5.2全局變量

例8-11有一個一維數(shù)組,內放10個學生成績,寫一個函數(shù),求出平均分,最高分和最低分。#include<stdio.h>floatMax,Min;floataverage(floatarray[],intn){inti;floataver,sum=array[0];Max=Min=array[0];for(i=1;i<n;i++){if(array[i]>Max)Max=array[i];elseif(array[i]<Min)Min=array[i];sum=sum+array[i];}aver=sum/n;return(aver);}voidmain(){floatave,score[10];inti;for(i=0;i<10;i++)scanf("%f",&score[i]);ave=average(score,10);printf("max=%6.2f\nmin=%6.2f\naverage=%6.2f\n",Max,Min,ave);}對于全局變量還有以下幾點說明:

(1)外部變量可加強函數(shù)模塊之間的數(shù)據(jù)聯(lián)系,但降低這些函數(shù)的獨立性。

(2)在同一源文件中,允許外部變量和內部變量同名。在內部變量的作用域內,外部變量將被屏蔽而不起作用。

(3)外部變量的作用域是從定義點到本文件結束。如果定義點之前的函數(shù)需要引用這些外部變量時,需要在函數(shù)內對被引用的外部變量進行說明。外部變量說明的一般形式為:extern數(shù)據(jù)類型

外部變量[,外部變量2……];注意:外部變量的定義和外部變量的說明是兩回事。外部變量的定義,必須在所有的函數(shù)之外,且只能定義一次。而外部變量的說明,出現(xiàn)在要使用該外部變量的函數(shù)內,而且可以出現(xiàn)多次。

#include<stdio.h>voidtestauto();voidmain(){inti;for(i=0;i<4;i++)testauto();printf("\n");}/*測試自動類局部變量的特性*/voidtestauto(){autointva=0;/*或intva=0;*/printf("%d”,va);va++;/*值不保留*/}自動變量的類型說明符為auto。這種存儲類型是C語言程序中使用最廣泛的一種類型。C語言規(guī)定,函數(shù)內凡未加存儲類型說明的變量均視為自動變量。例8-12測試自動類型局部變量的特性。8.6.1auto存儲類型

8.6存儲類型

自動變量具有以下特點:(1)自動變量的作用域僅限于定義該變量的區(qū)域內。在函數(shù)中定義的自動變量,只在該函數(shù)內有效。在復合語句中定義的自動變量只在該復合語句中有效。

例如:intkv(inta){autointx,y;{autocharc;}/*c的作用域*/……}/*a、x、y的作用域*/(2)自動變量屬于動態(tài)存儲方式,只有在定義該變量的函數(shù)被調用時才給它分配存儲單元,開始它的生存期。函數(shù)調用結束,釋放存儲單元,結束生存期。因此函數(shù)調用結束之后,自動變量的值不能保留。在復合語句中定義的自動變量,在退出復合語句后也不能再使用,否則將引起錯誤。例8-13變量的作用域----自動變量。voidmain(){autointa,s=1,p=2; printf("\ninputanumber:\n");scanf("%d",&a);if(a>0){autos,p;s=a+a;p=a*a;}printf("s=%dp=%d\n",s,p);}(3)由于自動變量的作用域和生存期都局限于定義它的個體內(函數(shù)或復合語句內),因此不同的個體中允許使用同名的變量而不會混淆。即使在函數(shù)內定義的自動變量也可與該函數(shù)內部的復合語句中定義的自動變量同名。外部變量的幾個特點:(1)外部變量和全局變量是對同一類變量的兩種不同角度的提法。全局變量是從它的作用域提出的,外部變量從它的存儲方式提出的,表示了它的生存期。(2)當一個源程序由若干個源文件組成時,在一個源文件中定義的外部變量在其它的源文件中也有效。例如F1.C:inta,b;/*外部變量定義*/charc;/*外部變量定義*/voidmain(){……}F2.C:externinta,b;/*外部變量說明*/externcharc;/*外部變量說明*/func(intx,y){……}8.6.2extern存儲類型

寄存器變量存放在CPU的寄存器中,使用時,不需要訪問內存,而直接從寄存器中讀寫,這樣可提高效率。變量的作用域----寄存器變量。#include<stdio.h>voidmain(){registerk,sum=0;for(k=1;k<=1000;k++)sum=sum+k;printf("sum=%d\n",sum);}8.6.3register存儲類型

1.靜態(tài)局部變量在局部變量的說明前再加上static說明符就構成靜態(tài)局部變量。例如:staticinta,b;staticfloatarray[5]={1,2,3,4,5};靜態(tài)局部變量屬于靜態(tài)存儲方式,它具有以下特點:(1)靜態(tài)局部變量在函數(shù)內定義,但不象自動變量那樣,當調用時就存在,退出函數(shù)時就消失。靜態(tài)局部變量始終存在著,也就是說它的生存期為整個源程序。(2)靜態(tài)局部變量的生存期雖然為整個源程序,但是其作用域仍與自動變量相同,即只能在定義該變量的函數(shù)內使用該變量。退出該函數(shù)后,盡管該變量還繼續(xù)存在,但不能使用它。(3)允許對構造類靜態(tài)局部量賦初值。(4)對基本類型的靜態(tài)局部變量若在說明時未賦以初值,則系統(tǒng)自動賦予0值。8.6.4static存儲類型靜態(tài)變量的作用域。#include<stdio.h>voidmain(){inti;voidf();/*函數(shù)說明*/for(i=1;i<=10;i++)f();/*函數(shù)調用*/}voidf()/*函數(shù)定義*/{staticintj=0;++j;printf("%d\n",j);}2.靜態(tài)全局變量在函數(shù)外部定義變量時,用static修飾的變量是靜態(tài)類全局變量。它分配在數(shù)據(jù)區(qū),作用范圍也是從定義點開始到該文件結束,或稱為文件作用域;但只限于該源文件,不能被其它源文件引用。靜態(tài)類全局變量在執(zhí)行main之前初始化;未初始化,其值為0。

溫馨提示

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

評論

0/150

提交評論