




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第9章函數模塊化程序設計基本思想:將一個大的程序按功能分割成一些小模塊,特點:各模塊相對獨立、功能單一、結構清晰、接口簡單控制了程序設計的復雜性提高元件的可靠性縮短開發周期避免程序開發的重復勞動易于維護和功能擴充開發方法:自上向下,逐步分解,分而治之C是模塊化程序設計語言C程序結構C是函數式語言必須有且只能有一個名為main的主函數C程序的執行總是從main函數開始,在main中結束函數不能嵌套定義,可以嵌套調用9.1函數分類從用戶角度標準函數(庫函數):由系統提供用戶自定義函數從函數形式無參函數有參函數使用庫函數應注意:1、函數功能2、函數參數的數目和順序,及各參數意義和類型3、函數返回值意義和類型4、需要使用的包含文件6.2函數的定義一般格式合法標識符函數返回值類型缺省int型無返回值void函數體函數類型函數名(形參類型說明表){
說明部分 語句部分}現代風格:例有參函數(現代風格)
intmax(intx,inty){intz;z=x>y?x:y;return(z);}例有參函數(現代風格)
intmax(intx,y){intz;z=x>y?x:y;return(z);}例空函數
dummy(){}函數體為空例無參函數
printstar(){printf(“**********\n”);}或
printstar(void){printf(“**********\n”);}例有參函數(傳統風格)
intmax(x,y)
intx,y;{intz;z=x>y?x:y;return(z);}6.3
函數的返回值返回語句形式:return(表達式);
或
return表達式;
或
return;功能:使程序控制從被調用函數返回到調用函數中,同時把返值帶給調用函數說明:函數中可有多個return語句若無return語句,遇}時,自動返回調用函數若函數類型與return語句中表達式值的類型不一致,按前者為準,自動轉換------函數調用轉換void型函數例無返回值函數
voidswap(intx,inty){inttemp;temp=x;x=y;y=temp;}printstar(){printf("**********");}main(){inta;a=printstar();printf("%d",a);}例函數帶回不確定值輸出:10voidprintstar(){printf("**********");}main(){inta;a=printstar();printf("%d",a);}編譯錯誤!6.4
函數的調用調用形式函數名(實參表);說明:實參與形參個數相等,類型一致,按順序一一對應實參表求值順序,因系統而定(TurboC自右向左)調用方式函數語句:例printstar();printf(“Hello,World!\n”);函數表達式:例m=max(a,b)*2;函數參數:例printf(“%d”,max(a,b));m=max(a,max(b,c));函數說明對被調用函數要求:必須是已存在的函數庫函數:#include<*.h>用戶自定義函數:函數類型說明函數說明一般形式:函數類型函數名(形參類型[形參名],…..);
或函數類型函數名();作用:告訴編譯系統函數類型、參數個數及類型,以便檢驗函數定義與函數說明不同函數說明位置:程序的數據說明部分(函數內或外)下列情況下,可不作函數說明若函數返值是char或int型,系統自動按int型處理被調用函數定義出現在主調函數之前例函數說明舉例main(){floata,b;intc;scanf("%f,%f",&a,&b);c=max(a,b);printf("Maxis%d\n",c);}max(floatx,floaty){floatz;z=x>y?x:y;return(z);}int型函數可不作函數說明(BorlandC++不行)floatadd(floatx,floaty){floatz;z=x+y;return(z);}main(){floata,b,c;scanf("%f,%f",&a,&b);c=add(a,b);printf("sumis%f",c);}被調函數出現在主調函數之前,不必函數說明main(){floatadd(float,float);/*functiondeclaration*/floata,b,c;scanf("%f,%f",&a,&b);c=add(a,b);printf("sumis%f",c);}floatadd(floatx,floaty){floatz;z=x+y;return(z);}floatadd();1.函數參數的傳遞傳值、傳地址2.地址參數舉例例題:swap(int*p,int*q)convert(inta,intn)
inversionstrcon(chara,charb)sushu(intm)maopao(inta,intn)3.遞歸n!fab(n)4.變量全局局部函數參數及其傳遞方式形參與實參形式參數:定義函數時函數名后面括號中的變量名實際參數:調用函數時函數名后面括號中的表達式c=max(a,b);(main函數)(max函數)max(intx,inty){intz;z=x>y?x:y;return(z);}例比較兩個數并輸出大者main(){inta,b,c;scanf("%d,%d",&a,&b);c=max(a,b);printf("Maxis%d",c);}max(intx,inty){intz;z=x>y?x:y;return(z);}形參實參說明:實參必須有確定的值形參必須指定類型形參與實參類型一致,個數相同若形參與實參類型不一致,自動按形參類型轉換———函數調用轉換形參在函數被調用前不占內存;函數調用時為形參分配內存;調用結束,內存釋放
函數參數及其傳遞方式形參與實參形式參數:定義函數時函數名后面括號中的變量名實際參數:調用函數時函數名后面括號中的表達式參數傳遞方式值傳遞方式方式:函數調用時,為形參分配單元,并將實參的值復制到形參中;調用結束,形參單元被釋放,實參單元仍保留并維持原值特點:形參與實參占用不同的內存單元單向傳遞711x:y:調用前:調用結束:711x:y:例交換兩個數#include<stdio.h>main(){intx=7,y=11;printf("x=%d,\ty=%d\n",x,y);printf("swapped:\n");
swap(x,y);printf("x=%d,\ty=%d\n",x,y);}swap(inta,intb){inttemp;temp=a;a=b;b=temp;}調用:711a:b:711x:y:swap:711x:y:117a:b:temp地址傳遞方式:函數調用時,將數據的存儲地址作為參數傳遞給形參特點:形參與實參占用同樣的存儲單元“雙向”傳遞實參和形參必須是地址常量或變量指針變量作為函數參數——地址傳遞特點:共享內存,“雙向”傳遞swap(intx,inty){inttemp;temp=x;x=y;y=temp;}main(){inta,b;scanf("%d,%d",&a,&b);if(a<b)swap(a,b);printf("\n%d,%d\n",a,b);}例
將數從大到小輸出…...…...20002008200A2002200420065變量a
變量b(main)9
變量temp
變量y
變量x(swap)55959COPY指針變量作為函數參數——地址傳遞特點:共享內存,“雙向”傳遞swap(intx,inty){inttemp;temp=x;x=y;y=temp;}main(){inta,b;scanf("%d,%d",&a,&b);if(a<b)swap(a,b);printf("\n%d,%d\n",a,b);}例
將數從大到小輸出值傳遞…...…...20002008200A2002200420065變量a
變量b(main)9運行結果:5,9swap(int*p1,int*p2){intp;p=*p1;*p1=*p2;*p2=p;}main(){inta,b;int*pointer_1,*pointer_2;scanf("%d,%d",&a,&b);
pointer_1=&a;pointer_2=&b;if(a<b)swap(pointer_1,pointer_2);printf("\n%d,%d\n",a,b);}…...20002008200A200220042006200C200E2010...59整型變量a
整型變量b(main)指針pointer_1指針pointer_220002002(swap)指針p1指針p2整型p5920002002COPY5例
將數從大到小輸出swap(int*p1,int*p2){intp;p=*p1;*p1=*p2;*p2=p;}main(){inta,b;int*pointer_1,*pointer_2;scanf("%d,%d",&a,&b);pointer_1=&a;pointer_2=&b;if(a<b)swap(pointer_1,pointer_2);printf("\n%d,%d\n",a,b);}…...20002008200A200220042006200C200E2010...59整型變量a
整型變量b(main)指針pointer_1指針pointer_22000200259例
將數從大到小輸出運行結果:9,5地址傳遞運行結果:5,9例
將數從大到小輸出swap(int*p1,int*p2){int*p;p=p1;p1=p2;p2=p;}main(){inta,b;int*pointer_1,*pointer_2;scanf("%d,%d",&a,&b);pointer_1=&a;pointer_2=&b;if(a<b)swap(pointer_1,pointer_2);printf("%d,%d",*pointer_1,*pointer_2);}…...20002008200A200220042006200C200E2010...59整型a
整型b(main)pointer_1pointer_22000200220002002COPY(swap)指針p1指針p2指針p****2000地址傳遞20002002數組名作函數參數數組名作函數參數,是地址傳遞數組名作函數參數,實參與形參的對應關系實參形參數組名指針變量數組名指針變量數組名數組名指針變量指針變量例將數組a中的n個整數按相反順序存放ij379110675420123456789ijijijji11760594723實參與形參均用數組voidinv(intx[],intn){intt,i,j;for(i=0,j=n-1;i<j;i++,j--){ t=x[i];x[i]=x[j];x[j]=t;}}main(){inti,a[10]={3,7,9,11,0,6,7,5,4,2};inv(a,10);printf("Thearrayhasbeenreverted:\n");for(i=0;i<10;i++)printf("%d,",a[i]);printf("\n");}m=4例將數組a中的n個整數按相反順序存放voidinv(int*x,intn){intt,*p,*i,*j;
for(i=x,j=x+n-1;;i<=j;i++,j--){t=*i;*i=*j;*j=t;}}main(){inti,a[10]={3,7,9,11,0,6,7,5,4,2};inv(a,10);printf("Thearrayhasbeenreverted:\n");for(i=0;i<10;i++)printf("%d,",a[i]);printf("\n");}實參用數組,形參用指針變量37911067542a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]xa數組60711594723ijijijjiji例將數組a中的n個整數按相反順序存放voidinv(intx[],intn){intt,i,j,m=(n-1)/2;for(i=0;i<=m;i++){j=n-1-i; t=x[i];x[i]=x[j];x[j]=t;}}main(){inti,a[10],*p=a;for(i=0;i<10;i++,p++)scanf("%d",p);
p=a;
inv(p,10);printf("Thearrayhasbeenreverted:\n");for(p=arr;p<arr+10;p++)printf("%d",*p);}實參用指針變量,形參用數組例編寫一個函數實現兩字符串的鏈接,在主函數中調用#include<stdio.h>voidscat(char*p,char*q){while(*p!='\0')p++;while(*q!='\0'){*p=*q;p++;q++;}*q='\0';}main(){chara[80],b[80];printf("請輸入兩個字符串\n");gets(a);gets(b);scat(a,b);printf("合并后的字符串是:\n");puts(a);}HELLO\0world\0函數的嵌套與遞歸調用嵌套調用C規定:函數定義不可嵌套,但可以嵌套調用函數main()調用函數a結束a函數b函數調用函數b例求三個數中最大數和最小數的差值#include<stdio.h>
intdif(intx,inty,intz);intmax(intx,inty,intz);intmin(intx,inty,intz);voidmain(){inta,b,c,d;scanf("%d%d%d",&a,&b,&c);
d=dif(a,b,c);printf("Max-Min=%d\n",d);}Ch7_202.cintdif(intx,inty,intz){returnmax(x,y,z)-min(x,y,z);}intmax(intx,inty,intz){intr;r=x>y?x:y;return(r>z?r:z);}intmin(intx,inty,intz){intr;r=x<y?x:y;return(r<z?r:z);}main()調用函數dif輸出結束dif函數max函數調用函數max調用函數minmin函數遞歸調用定義:函數直接或間接的調用自身叫函數的遞歸調用f()調f調f2調f1f1()f2()intf(intx){inty,z;……
z=f(y);…….return(2*z);}intf1(intx){inty,z;……
z=f2(y);…….return(2*z);}intf2(intt){inta,c;……
c=f1(a);…….return(3+c);}例求n的階乘#include<stdio.h>intfac(intn){intf;if(n<0)printf("n<0,dataerror!");elseif(n==0||n==1)f=1;elsef=fac(n-1)*n;return(f);}main(){intn,y;printf("Inputaintegernumber:");scanf("%d",&n);
y=fac(n);printf("%d!=%15d",n,y);}例求Fibonaci(n)9.5變量的存儲屬性概述變量是對程序中數據的存儲空間的抽象內存…….main(){inta;a=10;printf(“%d”,a);}編譯或函數調用時為其分配內存單元1020002001程序中使用變量名對內存操作變量的屬性數據類型:變量所持有的數據的性質(操作屬性)存儲屬性存儲器類型:寄存器、靜態存儲區、動態存儲區生存期:變量在某一時刻存在-------靜態變量與動態變量作用域:變量在某區域內有效-------局部變量與全局變量變量的存儲類型auto-----自動型register-----寄存器型static------靜態型extern-----外部型變量定義格式:[存儲類型]數據類型變量表;9.5變量的存儲屬性概述變量是對程序中數據的存儲空間的抽象如:intsum;
autointa,b,c;
registerinti;
staticfloatx,y;局部變量與全局變量局部變量---內部變量定義:在函數內定義,只在本函數內有效說明:main中定義的變量只在main中有效不同函數中同名變量,占不同內存單元形參屬于局部變量可定義在復合語句中有效的變量floatf1(inta){intb,c;…….}charf2(intx,inty){inti,j;……}main(){intm,n;…….}a,b,c有效x,y,i,j有效m,n有效例不同函數中同名變量main(){inta,b;a=3;b=4;printf("main:a=%d,b=%d\n",a,b);sub();printf("main:a=%d,b=%d\n",a,b);}sub(){inta,b;a=6;b=7;printf("sub:a=%d,b=%d\n",a,b);}例復合語句中變量#defineN5main(){inti;inta[N]={1,2,3,4,5};for(i=0;i<N/2;i++)
{
inttemp; temp=a[i]; a[i]=a[N-i-1]; a[N-i-1]=temp;
}for(i=0;i<N;i++)printf("%d",a[i]);}全局變量---外部變量定義:在函數外定義,可為本文件所有函數共用有效范圍:從定義變量的位置開始到本源文件結束,及有extern說明的其它源文件>外部變量說明:
extern數據類型變量表;若外部變量與局部變量同名,則外部變量被屏蔽intp=1,q=5;floatf1(inta){intb,c;…….}intf3(){…..}charc1,c2;charf2(intx,inty){inti,j;……}main(){intm,n;…….}c1,c2的作用范圍p,q的作用范圍externcharc1,c2;externcharc1,c2;c1,c2的作用范圍擴展后c1,c2的作用范圍擴展后局部靜態變量#in
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
評論
0/150
提交評論