版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、模塊化程序設(shè)計v基本思想:將一個大的程序按功能分割成一些小模塊,v特點:l各模塊相對獨立、功能單一、結(jié)構(gòu)清晰、接口簡單l控制了程序設(shè)計的復(fù)雜性l提高元件的可靠性l縮短開發(fā)周期l避免程序開發(fā)的重復(fù)勞動l易于維護和功能擴充第六章 函數(shù)C是模塊化程序設(shè)計語言源程序文件1預(yù)編譯命令說明部分執(zhí)行部分函數(shù)1函數(shù)n源程序文件i源程序文件nC程序C程序結(jié)構(gòu)&C是函數(shù)式語言&必須有且只能有一個名為main的主函數(shù)&C程序的執(zhí)行總是從main函數(shù)開始,在main中結(jié)束&函數(shù)不能嵌套定義,可以嵌套調(diào)用例、在 C 程序中 , 函數(shù)既可以嵌套定義 , 也可以嵌套調(diào)用。 函數(shù)分類v從用戶角
2、度l標(biāo)準(zhǔn)函數(shù)(庫函數(shù)):由系統(tǒng)提供l用戶自定義函數(shù)v從函數(shù)形式l無參函數(shù)l有參函數(shù)使用庫函數(shù)應(yīng)注意:1、函數(shù)功能2、函數(shù)參數(shù)的數(shù)目和順序,及各參數(shù)意義和類型3、函數(shù)返回值意義和類型4、需要使用的包含文件Ch7_201.c6.1 函數(shù)一、函數(shù)的定義一般格式合法標(biāo)識符函數(shù)返回值類型缺省int型無返回值void函數(shù)體函數(shù)類型 函數(shù)名(形參類型說明表)說明部分語句部分例 有參函數(shù)(現(xiàn)代風(fēng)格) int max(int x,int y) int z; z=xy?x:y; return(z); 例 有參函數(shù)(現(xiàn)代風(fēng)格) int max(int x, y) int z; z=xy?x:y; return(z)
3、; 例 空函數(shù) dummy( ) 函數(shù)體為空例 無參函數(shù) printstar( ) printf(“*n”); 或 printstar(void ) printf(“*n”); 返回語句v形式: return(表達(dá)式); 或 return 表達(dá)式; 或 return;v功能:使程序控制從被調(diào)用函數(shù)返回到調(diào)用函數(shù)中,同時把返值帶給調(diào)用函數(shù)v說明:l函數(shù)中可有多個return語句l若無return語句,遇時,自動返回調(diào)用函數(shù)l若函數(shù)類型與return語句中表達(dá)式值的類型不一致,按前者為準(zhǔn),自動轉(zhuǎn)換-函數(shù)調(diào)用轉(zhuǎn)換lvoid型函數(shù)例 無返回值函數(shù) void swap(int x,int y ) int
4、 temp; temp=x; x=y; y=temp; 例、編寫程序,輸入一個正整數(shù)n,求下列算式的值。要求定義和調(diào)用函數(shù)fact(k)計算k的階乘,函數(shù)返回值的類型是double。2006年春試題。11!nkskdouble fact(int k)double s=0; int i,t=1; for(i=1;i=k;i+) t=t*i; s=s+1.0/t; return s;二、函數(shù)的調(diào)用調(diào)用形式 函數(shù)名(實參表);說明:l實參與形參個數(shù)相等,類型一致,按順序一一對應(yīng)l實參表求值順序,因系統(tǒng)而定(Turbo C 自右向左)#include main()intn; double sum; s
5、canf(“%d”,&n);sum=fact(n);/函數(shù)調(diào)用Printf(“%f”,sum);調(diào)用方式v函數(shù)語句: 例 printstar(); printf(“Hello,World!n”);v函數(shù)表達(dá)式: 例 m=max(a,b)*2;v函數(shù)參數(shù): 例 printf(“%d”,max(a,b); m=max(a,max(b,c);main() int i=2,j=2,p; p=f(i,j); printf(%d,p);int f(int a, int b) int c; if(ab) c=1; else if(a=b) c=0; else c=-1; return(c);例 參數(shù)
6、求值順序運行結(jié)果:0調(diào)用函數(shù)語句1;主調(diào)函數(shù)主調(diào)函數(shù)Return語句或最后一個執(zhí)行函數(shù)調(diào)用的內(nèi)涵:1、把實參的值傳給形參;2、把控制語句傳給被調(diào)函數(shù);也就是說程序的執(zhí)行由主調(diào)函轉(zhuǎn)到被調(diào)函數(shù);3、在函數(shù)中執(zhí)行return語句,將返回值帶回到主調(diào)函數(shù)。 printstar() printf(*);main() int a; a=printstar(); printf(%d,a);例 函數(shù)帶回不確定值輸出:10void printstar() printf(*);main() int a; a=printstar(); printf(%d,a);編譯錯誤!例 函數(shù)返回值類型轉(zhuǎn)換main() floa
7、t a,b; int c; scanf(%f,%f,&a,&b); c=max(a,b); printf(Max is %dn,c);max(float x, float y) float z; z=xy?x:y; return(z);三、函數(shù)參數(shù)及其傳遞方式形參與實參v形式參數(shù):定義函數(shù)時函數(shù)名后面括號中的變量名v實際參數(shù):調(diào)用函數(shù)時函數(shù)名后面括號中的表達(dá)式c=max(a,b);(main 函數(shù))(max 函數(shù))max(int x, int y) int z; z=xy?x:y; return(z); 例 比較兩個數(shù)并輸出大者main() int a,b,c; scanf(%
8、d,%d,&a,&b); c=max(a,b); printf(Max is %d,c);max(int x, int y) int z; z=xy?x:y; return(z);形參實參v說明1:l實參必須有確定的值l形參必須指定類型l形參與實參類型一致,個數(shù)相同l若形參與實參類型不一致,自動按形參類型轉(zhuǎn)換函數(shù)調(diào)用轉(zhuǎn)換l形參在函數(shù)被調(diào)用前不占內(nèi)存;函數(shù)調(diào)用時為形參分配內(nèi)存;調(diào)用結(jié)束,內(nèi)存釋放形參與實參v形式參數(shù):定義函數(shù)時函數(shù)名后面括號中的變量名v實際參數(shù):調(diào)用函數(shù)時函數(shù)名后面括號中的表達(dá)式說明說明2 2:1.1.形參只有在函數(shù)調(diào)用時才分配存儲單元,調(diào)用結(jié)束后,形參只有在函數(shù)
9、調(diào)用時才分配存儲單元,調(diào)用結(jié)束后,釋放所分配的單元釋放所分配的單元; 2.2.實參可以是常量、變量、表達(dá)式,總之實參可以是常量、變量、表達(dá)式,總之要有確定的值要有確定的值,當(dāng)函數(shù)調(diào)用時,將實參的值傳遞給形參,若是數(shù)組名,當(dāng)函數(shù)調(diào)用時,將實參的值傳遞給形參,若是數(shù)組名,則傳送的是數(shù)組的首地址。則傳送的是數(shù)組的首地址。 3.3.被調(diào)函數(shù)中,形參類型必須指定,以便分配存儲單元。被調(diào)函數(shù)中,形參類型必須指定,以便分配存儲單元。 4 4. .實參、形參的數(shù)據(jù)類型一致實參、形參的數(shù)據(jù)類型一致,賦值要兼容,順序要一致。,賦值要兼容,順序要一致。 5.5.若被調(diào)函數(shù)類型為非整形,要在主調(diào)函數(shù)中對被調(diào)函數(shù)若被調(diào)
10、函數(shù)類型為非整形,要在主調(diào)函數(shù)中對被調(diào)函數(shù)作原形聲明或在主調(diào)函數(shù)之前定義。作原形聲明或在主調(diào)函數(shù)之前定義。 6.6.實參對形參的數(shù)據(jù)傳送是值傳送,也是單向傳送實參對形參的數(shù)據(jù)傳送是值傳送,也是單向傳送,當(dāng)被,當(dāng)被調(diào)函數(shù)的形參發(fā)生變化時,并不改變主調(diào)函數(shù)實參的值。調(diào)函數(shù)的形參發(fā)生變化時,并不改變主調(diào)函數(shù)實參的值。 例 計算x的立方#include float cube(float x) return(x*x*x);main() float a, product; printf(Please input value of a:); scanf(%f,&a); product=cube(a)
11、; printf(”Cube of %.4f is %.4fn,a,product);xaproduct1.21.21.7281、參數(shù)傳遞方式v值傳遞方式l方式:函數(shù)調(diào)用時,為形參分配單元,并將實參的值復(fù)制到形參中;調(diào)用結(jié)束,形參單元被釋放,實參單元仍保留并維持原值l特點:u形參與實參占用不同的內(nèi)存單元u單向傳遞711x:y:調(diào)用前:調(diào)用結(jié)束:711x:y:例 交換兩個數(shù)/*ch7_2.c*/#include main() int x=7,y=11; printf(x=%d,ty=%dn,x,y); printf(swapped:n); swap(x,y); printf(x=%d,ty=%d
12、n,x,y);swap(int a,int b) int temp; temp=a; a=b; b=temp;調(diào)用:711a:b:711x:y:swap:711x:y:117a:b:temp函數(shù)說明v對被調(diào)用函數(shù)要求:l必須是已存在的函數(shù)l庫函數(shù): #include l用戶自定義函數(shù): 函數(shù)類型說明v函數(shù)說明l一般形式: 函數(shù)類型 函數(shù)名(形參類型 形參名,. ); 或 函數(shù)類型 函數(shù)名();l作用:告訴編譯系統(tǒng)函數(shù)類型、參數(shù)個數(shù)及類型,以便檢驗l函數(shù)定義與函數(shù)說明不同l函數(shù)說明位置:程序的數(shù)據(jù)說明部分(函數(shù)內(nèi)或外)l下列情況下,可不作函數(shù)說明u若函數(shù)返值是char或int型,系統(tǒng)自動按int
13、型處理u被調(diào)用函數(shù)定義出現(xiàn)在主調(diào)函數(shù)之前l(fā)有些系統(tǒng)(如Borland C+)要求函數(shù)說明指出函數(shù)返值類型和形參類型,并且對void 和 int 型函數(shù)也要進行函數(shù)說明例 函數(shù)說明舉例main() float a,b; int c; scanf(%f,%f,&a,&b); c=max(a,b); printf(Max is %dn,c);max(float x, float y) float z; z=xy?x:y; return(z);int型函數(shù)可不作函數(shù)說明(Borland C+不行)/*ch7_5.c*/float add(float x, float y) float
14、z; z=x+y; return(z);main() float a,b,c; scanf(%f,%f,&a,&b); c=add(a,b); printf(sum is %f,c);被調(diào)函數(shù)出現(xiàn)在主調(diào)函數(shù)之前,不必函數(shù)說明/*ch7_5.c*/main() float add(float,float); /*function declaration*/ float a,b,c; scanf(%f,%f,&a,&b); c=add(a,b); printf(sum is %f,c);float add(float x, float y) float z; z=x
15、+y; return(z);float add();二、地址傳遞l 方式:函數(shù)調(diào)用時,將數(shù)據(jù)的存儲地址作為參數(shù)傳遞給形參l 特點:u形參與實參占用同樣的存儲單元u“雙向”傳遞u實參和形參必須是地址常量或變量l 方法有兩種u指針作函數(shù)的參數(shù)u數(shù)組作函數(shù)的參數(shù)1、指針作函數(shù)的參數(shù)(1)、用指針(地址)作函數(shù)參數(shù),可以實現(xiàn))、用指針(地址)作函數(shù)參數(shù),可以實現(xiàn)“通過被調(diào)用的函數(shù)改變主通過被調(diào)用的函數(shù)改變主調(diào)函數(shù)中變量的值調(diào)函數(shù)中變量的值”的目的。的目的。 (2)、使用指針作為函數(shù)參數(shù)可以在調(diào)用一個函數(shù)時得到多)、使用指針作為函數(shù)參數(shù)可以在調(diào)用一個函數(shù)時得到多 個由被調(diào)函個由被調(diào)函數(shù)改變了的值。數(shù)改變
16、了的值。/*ch9_3.c*/swap(int *p1,int *p2) int p; p=*p1; *p1=*p2; *p2=p;main() int a,b; scanf(%d,%d,&a,&b); printf(“a=%d,b=%dn”,a,b); printf(“swapped:n”); swap(&a,&b); printf(”a=%d,b=%dn,a,b);例 交換兩個數(shù)a59b調(diào)前:a59b調(diào)swap:p1&a&bp2a95b交換:p1&a&bp2a95b返回:例如:有一數(shù)組有10個元素,要求輸出其中最大和最小的元素
17、值。#define N 10 main ( ) void max_min(int arr , int *pt1, int *pt2,int n); int arrayN=1,8,10,2,-5,0,7,15,4,-5,*p1,*p2,a,b; p1=&a;p2=&b; max_min(array,p1,p2,N); printf(“max=%d,min=%d”,a,b); void max_min(int arr ,int *pt1,int *pt2,int n) int I; *pt1=*pt2=arr0; for(I-=1;I*pt1) *pt1=arrI; if(arrI
18、*pt2) *pt2=arrI; p1 apt1p2 bpt2函數(shù)的嵌套與遞歸調(diào)用(加)嵌套調(diào)用C規(guī)定:函數(shù)定義不可嵌套,但可以嵌套調(diào)用函數(shù)main( )調(diào)用函數(shù)a結(jié)束a函數(shù)b函數(shù)調(diào)用函數(shù)b例 求三個數(shù)中最大數(shù)和最小數(shù)的差值#include int dif(int x,int y,int z); int max(int x,int y,int z); int min(int x,int y,int z);void main() int a,b,c,d; scanf(%d%d%d,&a,&b,&c); d=dif(a,b,c); printf(Max-Min=%dn,d)
19、; Ch7_202.cint dif(int x,int y,int z) return max(x,y,z)-min(x,y,z); int max(int x,int y,int z) int r; r=xy?x:y; return(rz?r:z); int min(int x,int y,int z) int r; r=xy?x:y; return(rz?r:z); main( )調(diào)用函數(shù)dif輸出結(jié)束dif函數(shù)max函數(shù)調(diào)用函數(shù)max調(diào)用函數(shù)minmin函數(shù)例 用弦截法求方程根08016523xxxxyf(x)0 x1x2xf(x1)f(x2)()()()(121221xfxfxfxx
20、fxx求f(x1)與f(x2)連線與x軸的交點x輸入x1,x2,求f(x1),f(x2)直到f(x1)與f(x2)異號y=f(x),y1=f(x1)y與y1同號真假x1=xy1=yx2=x直到 |y|root=x 輸出 rootroot函數(shù)運行情況:Input x1,x2:2,6A root of equation is 5.0000main( )調(diào)用函數(shù)root輸出根 x結(jié)束root函數(shù)xpoint函數(shù)調(diào)用函數(shù)xpoint調(diào)用函數(shù)ff函數(shù)遞歸調(diào)用v定義:函數(shù)直接或間接的調(diào)用自身叫函數(shù)的遞歸調(diào)用f( )調(diào)f調(diào)f2調(diào)f1f1( )f2( )v說明lC編譯系統(tǒng)對遞歸函數(shù)的自調(diào)用次數(shù)沒有限制l每調(diào)用
21、函數(shù)一次,在內(nèi)存堆棧區(qū)分配空間,用于存放函數(shù)變量、返回值等信息,所以遞歸次數(shù)過多,可能引起堆棧溢出int f(int x) int y,z; z=f(y); . return(2*z);int f1(int x) int y,z; z=f2(y); . return(2*z);int f2(int t) int a,c; c=f1(a); . return(3+c);例 求n的階乘) 1()!1() 1 , 0(1!nnnnn/*ch7_8.c*/#include int fac(int n) int f; if(n0) printf(n%c#”,a,b); else f(n-1,a,c,b)
22、; printf(“%c-%c#”,a,b); f(n- 1,c,b,a); A1#13#32# B32#12#13#C13#32#12# D13#12#32#6.2 函數(shù)參數(shù)一、數(shù)組元素作函數(shù)實參值傳遞例 兩個數(shù)組大小比較432105a562312107688432105b212343986654n=0m=0k=0in=0m=0k=1in=0m=1k=1in=1m=1k=1in=1m=1k=2in=2m=1k=2in=3m=1k=2a和b為有10個元素的整型數(shù)組比較兩數(shù)組對應(yīng)元素變量n,m,k記錄aibi, ai=bi,aik,認(rèn)為數(shù)組ab 若nk,認(rèn)為數(shù)組ab 若n=k,認(rèn)為數(shù)組a=b#i
23、nclude main() int a10,b10,i,n=0,m=0,k=0; printf(Enter array a:n); for(i=0;i10;i+)scanf(%d,&ai); printf(Enter array b:n); for(i=0;i10;i+)scanf(%d,&bi); for(i=0;iy) flag=1; else if(xy) flag=-1; else flag=0; return(flag);數(shù)組名作函數(shù)參數(shù)v地址傳遞v在主調(diào)函數(shù)與被調(diào)函數(shù)分別定義數(shù)組,且類型應(yīng)一致v形參數(shù)組大小(多維數(shù)組第一維)可不指定v形參數(shù)組名是地址變量例 求學(xué)生的
24、平均成績 #include float average(int stu10, int n); void main() int score10, i; float av; printf(Input 10 scores:n); for( i=0; i10; i+ ) scanf(%d, &scorei); av=average(score,10); printf(Average is:%.2f, av); float average(int stu10, int n) int i; float av,total=0; for( i=0; in; i+ ) total += stui; av
25、 = total/n; return av; 實參用數(shù)組名形參用數(shù)組定義, int stu .2109score562312.88stu例 數(shù)組元素與 數(shù)組名 作函數(shù)參數(shù)比較12a調(diào)用前a0a112a調(diào)用a0a112xy21xy交換12a返回#include void swap2(int x,int y) int z; z=x; x=y; y=z;main() int a2=1,2; swap2(a0,a1); printf(a0=%dna1=%dn,a0,a1);值傳遞12a調(diào)用前12ax調(diào)用21ax交換21a返回#include void swap2(int x) int z; z=x0;
26、 x0=x1; x1=z;main() int a2=1,2; swap2(a); printf(a0=%dna1=%dn,a0,a1);地址傳遞例 數(shù)組元素與 數(shù)組名 作函數(shù)參數(shù)比較例 數(shù)組排序-簡單選擇排序void sort(int array,int n) int i,j,k,t; for(i=0;in-1;i+) k=i; for(j=i+1;jn;j+) if(arrayjarrayk) k=j; if(k!=i) t=arrayi; arrayi=arrayk; arrayk=t; main() int a10,i; for(i=0;i10;i+)scanf(%d,&ai)
27、; sort(a,10); for(i=0;i10;i+) printf(%d ,ai); printf(n);0123456789a4968573299927137688arraykjjjkjkjjjjj949i=0例 數(shù)組排序-簡單選擇排序void sort(int array,int n) int i,j,k,t; for(i=0;in-1;i+) k=i; for(j=i+1;jn;j+) if(arrayjarrayk) k=j; if(k!=i) t=arrayi; arrayi=arrayk; arrayk=t; main() int a10,i; for(i=0;i10;i+)
28、scanf(%d,&ai); sort(a,10); for(i=0;i10;i+) printf(%d ,ai); printf(n);kjjkjkjjjjj0123456789a4968573299927137688array949kk1368i=10123456789a9132732495768768899arrayi=8例 數(shù)組排序-簡單選擇排序void sort(int array,int n) int i,j,k,t; for(i=0;in-1;i+) k=i; for(j=i+1;jn;j+) if(arrayjarrayk) k=j; if(k!=i) t=arrayi
29、; arrayi=arrayk; arrayk=t; main() int a10,i; for(i=0;i10;i+)scanf(%d,&ai); sort(a,10); for(i=0;i10;i+) printf(%d ,ai); printf(n);例 求二維數(shù)組中最大元素值1 3 5 72 4 6 815 17 34 12ijmax=11 3 5 72 4 6 815 17 34 12ijmax=31 3 5 72 4 6 815 17 34 12ijmax=5j1 3 5 72 4 6 815 17 34 12imax=7j1 3 5 72 4 6 815 17 34 12
30、imax=7j1 3 5 72 4 6 815 17 34 12imax=34int max_value(int array34) int i,j,k,max; max=array00; for(i=0;i3;i+) for(j=0;jmax) max=arrayij; return(max);main() int a34=1,3,5,7, 2,4,6,8,15,17,34,12; printf(max value is %dn,max_value(a);多維形參數(shù)組第一維維數(shù)可省略,第二維必須相同 int array4例 求二維數(shù)組中各行元素之和get_sum_row(int x3, int
31、 result ,int row, int col) int i,j; for(i=0;irow;i+) resulti=0;for(j=0;jcol;j+) resulti+=xij; main() int a23=3,6,9,1,4,7; int sum_row2,row=2,col=3,i; get_sum_row(a,sum_row,row,col); for(i=0;irow;i+) printf(The sum of row%d=%dn,i+1,sum_rowi);314679asum_rowxresult1812幾點說明:幾點說明: 1.1.數(shù)組名作形、實參數(shù)時,應(yīng)分別在主、被調(diào)
32、函數(shù)中對數(shù)組名作形、實參數(shù)時,應(yīng)分別在主、被調(diào)函數(shù)中對其聲明其聲明 2.2.形、實參數(shù)的數(shù)組類型要一致,大小一般相等形、實參數(shù)的數(shù)組類型要一致,大小一般相等,以保,以保證數(shù)據(jù)的全部傳送;證數(shù)據(jù)的全部傳送; 3.3.當(dāng)形參數(shù)組大小未指定時,用一實參將數(shù)組長度傳遞當(dāng)形參數(shù)組大小未指定時,用一實參將數(shù)組長度傳遞給形參以便對數(shù)組進行操作給形參以便對數(shù)組進行操作; 4.4.數(shù)組名作參數(shù)時,傳遞的是地址,對形參數(shù)組的操作數(shù)組名作參數(shù)時,傳遞的是地址,對形參數(shù)組的操作實際上也是對實參數(shù)組的操作。實際上也是對實參數(shù)組的操作。 6.2.2 字符串指針作函數(shù)參數(shù)字符串指針作函數(shù)參數(shù) 將一個字符串從一個函數(shù)傳遞到另
33、一個函數(shù),可以采用地址傳將一個字符串從一個函數(shù)傳遞到另一個函數(shù),可以采用地址傳遞的辦法,即將字符數(shù)組名作參數(shù)或用指向字符串的指針變量作參遞的辦法,即將字符數(shù)組名作參數(shù)或用指向字符串的指針變量作參數(shù)。在被調(diào)用的函數(shù)中可以改變字符串的內(nèi)容,在主調(diào)函數(shù)中可以數(shù)。在被調(diào)用的函數(shù)中可以改變字符串的內(nèi)容,在主調(diào)函數(shù)中可以得到改變了的字符串。得到改變了的字符串。voidvoid copy_string(from,to) copy_string(from,to)char from,to;char from,to;int i=0;int i=0; while (fromi!=0) while (fromi!=0
34、) toi=fromi; toi=fromi;i+;i+; toi=0;toi=0; main()main()char a=I am a teacher.;char a=I am a teacher.; char b=you are a student.; char b=you are a student.;printf(string_a=%snstring_b=%sprintf(string_a=%snstring_b=%sn,a,b);n,a,b); copy_string(a,b);copy_string(a,b);printf(nstring_a=%snstring_b=printf(
35、nstring_a=%snstring_b=%sn,a,b);%sn,a,b); 1)形參和實參都用用字符數(shù)組作參數(shù),程序。)形參和實參都用用字符數(shù)組作參數(shù),程序。void void copy_string(from,to)copy_string(from,to)char char * *from,from,* *toto; ;for for (;(;* *from!=0;from+,tofrom!=0;from+,to+)+) * *to=to=* *from;from; * *to=0;to=0; main()main()char a=I am a teacher.;char a=I am
36、 a teacher.; char b=you are a student.; char b=you are a student.; printf(string_a=%snstring_b=%sprintf(string_a=%snstring_b=%sn,a,b);n,a,b); copy_string( copy_string(a,ba,b);); printf(nstring_a=%snstring_b=printf(nstring_a=%snstring_b=%sn,a,b);%sn,a,b); 2)形參用字符指針變量,實參用數(shù)組名。)形參用字符指針變量,實參用數(shù)組名。另外形參和實參都
37、用字符另外形參和實參都用字符指針,以及形參用字符數(shù)指針,以及形參用字符數(shù)組名,實參用字符指針在組名,實參用字符指針在10.3.2中已經(jīng)講過,不再重中已經(jīng)講過,不再重復(fù)復(fù)。3)copy_string函數(shù)的簡化函數(shù)的簡化6.3 6.3 函數(shù)指針函數(shù)指針 一個函數(shù)包括一組指令序列,存儲在某一段內(nèi)存中,這段一個函數(shù)包括一組指令序列,存儲在某一段內(nèi)存中,這段內(nèi)存空間的起始地址稱為內(nèi)存空間的起始地址稱為函數(shù)的入口地址函數(shù)的入口地址 稱函數(shù)入口地址為稱函數(shù)入口地址為函數(shù)的指針。函數(shù)名函數(shù)的指針。函數(shù)名代表函數(shù)的入口地代表函數(shù)的入口地址址 可以定義一個指針變量,其值等于該函數(shù)的入口地址,指可以定義一個指針變量
38、,其值等于該函數(shù)的入口地址,指向這個函數(shù),這樣通過這個指針變量也能調(diào)用這個函數(shù)。這種向這個函數(shù),這樣通過這個指針變量也能調(diào)用這個函數(shù)。這種指針變量稱為指針變量稱為指向函數(shù)的指針變量。指向函數(shù)的指針變量。定義指向函數(shù)的指針變量的一般形式為定義指向函數(shù)的指針變量的一般形式為: 類型標(biāo)識符(類型標(biāo)識符(* *指針變量名指針變量名)( )( );例:例:int (*p)(); /* 指針變量指針變量p可以指向一個整型函數(shù)可以指向一個整型函數(shù)*/ float (*q)(); /* 指針變量指針變量q可以指向一個浮點型函數(shù)可以指向一個浮點型函數(shù)*/下一頁下一頁上一頁上一頁 剛定義的指向函數(shù)的指針變量,亦象
39、其它指針變剛定義的指向函數(shù)的指針變量,亦象其它指針變量一樣要賦以地址值才能引用。當(dāng)將某個函數(shù)的入口量一樣要賦以地址值才能引用。當(dāng)將某個函數(shù)的入口地址賦給指向函數(shù)的指針變量,就可用該指針變量來地址賦給指向函數(shù)的指針變量,就可用該指針變量來調(diào)用所指向的函數(shù)調(diào)用所指向的函數(shù) 給函數(shù)指針賦初值:將函數(shù)名(函數(shù)的入口地址給函數(shù)指針賦初值:將函數(shù)名(函數(shù)的入口地址值)賦給指針變量值)賦給指針變量 例如例如 int m, (*p)( ); int max(int a,int b);則可以則可以 p=max; /* p指向函數(shù)指向函數(shù)max() */指針調(diào)用函數(shù)的指針調(diào)用函數(shù)的 一般形式為一般形式為: (*
40、*指針變量指針變量)( )( 實參表實參表) ); 如上例:如上例:m=(*p)(12,22); /*比較比較 m=max(12,22); */下一頁下一頁上一頁上一頁 用函數(shù)指針調(diào)用函數(shù)是間接調(diào)用,沒有參數(shù)類型用函數(shù)指針調(diào)用函數(shù)是間接調(diào)用,沒有參數(shù)類型說明,說明,C編譯系統(tǒng)也無法進行類型檢查,因此,在使編譯系統(tǒng)也無法進行類型檢查,因此,在使用這種形式調(diào)用函數(shù)時要特別小心。實參一定要和用這種形式調(diào)用函數(shù)時要特別小心。實參一定要和指針?biāo)负瘮?shù)的形參類型一致。指針?biāo)负瘮?shù)的形參類型一致。 函數(shù)指針可以作為函數(shù)參數(shù),此時,當(dāng)函數(shù)指針函數(shù)指針可以作為函數(shù)參數(shù),此時,當(dāng)函數(shù)指針每次指向不同的函數(shù)時,可執(zhí)
41、行不同的函數(shù)來完成每次指向不同的函數(shù)時,可執(zhí)行不同的函數(shù)來完成不同的功能不同的功能 下一頁下一頁上一頁上一頁注意注意例例 函數(shù)函數(shù)max()max()用來求一維數(shù)組的元素的最大值,在用來求一維數(shù)組的元素的最大值,在主調(diào)函數(shù)中用函數(shù)名調(diào)用該函數(shù)與用函數(shù)指針調(diào)用主調(diào)函數(shù)中用函數(shù)名調(diào)用該函數(shù)與用函數(shù)指針調(diào)用該函數(shù)來實現(xiàn)。該函數(shù)來實現(xiàn)。下一頁下一頁上一頁上一頁#include stdio.h #define M 8 main()float sumf,sump; float aM=11,2,-3,4.5,5,69,7,80; float (*p)(); /*定義指向函數(shù)的指針定義指向函數(shù)的指針p*/ f
42、loat max(float a ,int n); /*函數(shù)聲明函數(shù)聲明*/ p=max; /*函數(shù)名(函數(shù)入口地址)賦給指針函數(shù)名(函數(shù)入口地址)賦給指針p*/sump=(*p)(a,M); /*用指針方式調(diào)用函數(shù)用指針方式調(diào)用函數(shù)*/sumf=max(a,M); /*用函數(shù)名調(diào)用用函數(shù)名調(diào)用max()函數(shù)函數(shù)*/ printf(sump=%.2fn,sump); printf(sumf=%.2fn,sumf); float max(float a,int n) int k;float s;s=a0;for (k=0;kn;k+) if (sak) s=ak; return s;下一頁下一頁
43、上一頁上一頁程序運行結(jié)果:程序運行結(jié)果: sump=80.00 sumf=80.00(1) 定義一個指向函數(shù)的指針變量,形如:定義一個指向函數(shù)的指針變量,形如: float (*p)();(2) 為函數(shù)指針賦值,格式如下:為函數(shù)指針賦值,格式如下: p=函數(shù)名;函數(shù)名; 注意:賦值時只需給出函數(shù)名,不要帶參數(shù)。注意:賦值時只需給出函數(shù)名,不要帶參數(shù)。(3) 通過函數(shù)指針調(diào)用函數(shù),調(diào)用格式如下:通過函數(shù)指針調(diào)用函數(shù),調(diào)用格式如下: s=(*p)(實參實參);上一頁上一頁指向函數(shù)的指針的使用步驟指向函數(shù)的指針的使用步驟返回函數(shù)指針的作用:函數(shù)指針的作用: 用函數(shù)指針變量作函數(shù)的參數(shù)用函數(shù)指針變量作
44、函數(shù)的參數(shù) 函數(shù)的參數(shù)既可以是變量函數(shù)的參數(shù)既可以是變量,常量常量,指針變量指針變量,數(shù)組名數(shù)組名,數(shù)組指針變量數(shù)組指針變量,也也可以是函數(shù)指針或函數(shù)指針變量可以是函數(shù)指針或函數(shù)指針變量;以便實現(xiàn)函數(shù)地址的傳送以便實現(xiàn)函數(shù)地址的傳送,達(dá)到用某達(dá)到用某個函數(shù)調(diào)用其他的函數(shù)個函數(shù)調(diào)用其他的函數(shù).函數(shù)的調(diào)用方式函數(shù)的調(diào)用方式:1. 直接使用直接使用函數(shù)名函數(shù)名2.間接調(diào)用間接調(diào)用通過通過函數(shù)指針函數(shù)指針0YXhf(b)= f(a+n*h)baf(a)共共n等份等份f(x)h=(b-a)/nf(a+h)f(a+(n-1)*h)baf(x)dxs=/ /* *1+1+x x2 2* */ /float
45、f1(x)float f1(x)float x;float x;float f;float f; f=1+x f=1+x* *x; x; return(f);return(f); float f3(x)float f3(x)float x;float x;float f; float f; f=x/(1+xf=x/(1+x* *x);x); return(f); return(f); / /* *1+1+x+xx+x2 2+x+x3 3* */ /float f2(x)float f2(x)float x;float x;float f;float f; f=1+x+x f=1+x+x* *x
46、+xx+x* *x x* *x;x; return(f); return(f); 多層間接調(diào)用多層間接調(diào)用_即用即用函數(shù)指針變量作函數(shù)的參數(shù)函數(shù)指針變量作函數(shù)的參數(shù),在調(diào)用一個通在調(diào)用一個通 用函數(shù)時用函數(shù)時,便于處理多種情況便于處理多種情況,以便選用各種專用以便選用各種專用 的函數(shù)的函數(shù).這樣做的好處是使得程序通用性強這樣做的好處是使得程序通用性強, 結(jié)構(gòu)結(jié)構(gòu) 模塊化程度高模塊化程度高.例例 求不同被積函數(shù)的積分求不同被積函數(shù)的積分x x1+1+x x2 2x x y1=01(1+(1+x x2 2)dx)dx y2=02(1+(1+x+xx+x2 2+x+x3 3)dx)dx03.51+1
47、+x x2 2x xy3=dxfloat integral(float integral(funfun,a,b),a,b)float float ( (* *fun)(),fun)(),a,b;a,b;float s,h,y;float s,h,y; int n,i; int n,i;s=(s=( (* *fun)(a)fun)(a)+ +( (* *fun)(b)fun)(b)/)/2.02.0; ; n=100; n=100; h=(b-a)/n; h=(b-a)/n; for (i=1;in;i+) for (i=1;iy) return (&x); else return (&
48、amp;y); 下一頁下一頁上一頁上一頁6.5 6.5 命令行參數(shù)命令行參數(shù) 在操作系統(tǒng)命令狀態(tài)下,可以輸入程序或命令使在操作系統(tǒng)命令狀態(tài)下,可以輸入程序或命令使其運行,稱命令行狀態(tài)。輸入的命令(或運行程序)其運行,稱命令行狀態(tài)。輸入的命令(或運行程序)及該命令(或程序)所需的參數(shù)稱為命令行參數(shù)。及該命令(或程序)所需的參數(shù)稱為命令行參數(shù)。 如如: : copy fd fs copy fd fs copycopy是文件拷貝命令,是文件拷貝命令,fdfd、fsfs是命令行參數(shù)。是命令行參數(shù)。mainmain函數(shù)是可以有參數(shù)的,但與普通函數(shù)不同。函數(shù)是可以有參數(shù)的,但與普通函數(shù)不同。帶形參的帶形參
49、的main( )main( )函數(shù)的一般形式是:函數(shù)的一般形式是:main (int argc, char main (int argc, char * *argv )argv ) 形參形參argcargc記錄命令行中字符串的個數(shù),記錄命令行中字符串的個數(shù),argvargv是一個字是一個字符型指針數(shù)組,每一個元素順序指向命令行中的一個符型指針數(shù)組,每一個元素順序指向命令行中的一個字符串。字符串。下一頁下一頁上一頁上一頁1.main()1.main()函數(shù)的形參與實參函數(shù)的形參與實參 mainmain()函數(shù)由系統(tǒng)自動調(diào)用,而不是被程序內(nèi)部的()函數(shù)由系統(tǒng)自動調(diào)用,而不是被程序內(nèi)部的其它函數(shù)調(diào)用
50、,其它函數(shù)調(diào)用, main()main()函數(shù)所需的實參不可能由程序內(nèi)函數(shù)所需的實參不可能由程序內(nèi)部得到,而是由系統(tǒng)傳送。部得到,而是由系統(tǒng)傳送。 mainmain()函數(shù)所需的實參與形參的傳遞方式也與一般()函數(shù)所需的實參與形參的傳遞方式也與一般函數(shù)的參數(shù)傳遞不同,實參是在命令行與程序名一同輸入,函數(shù)的參數(shù)傳遞不同,實參是在命令行與程序名一同輸入,程序名和各實際參數(shù)之間都用空格分隔。程序名和各實際參數(shù)之間都用空格分隔。格式為:執(zhí)行程序名格式為:執(zhí)行程序名 參數(shù)參數(shù)1 1 參數(shù)參數(shù)2 2 參數(shù)參數(shù)n n形參形參argcargc為命令行中參數(shù)的個數(shù)為命令行中參數(shù)的個數(shù)(包括執(zhí)行程序名),其(包括
51、執(zhí)行程序名),其值大于或等于值大于或等于1 1,而不是象普通,而不是象普通C C語言函數(shù)一樣接受第一個語言函數(shù)一樣接受第一個實參。實參。形參形參argvargv是一個指針數(shù)組,其元素依次指向命令行中以空是一個指針數(shù)組,其元素依次指向命令行中以空格分開的各字符串。格分開的各字符串。即:第一個指針即:第一個指針argv0argv0指向程序名字符串指向程序名字符串,argv1,argv1指向指向參數(shù)參數(shù)1 1,argv2argv2指向參數(shù)指向參數(shù)2 2,.,argvn argvn 指向參數(shù)指向參數(shù)n n。下一頁下一頁上一頁上一頁2. 2.命令行參數(shù)的傳遞示例命令行參數(shù)的傳遞示例例例8.11 8.11
52、 分析下列程序,指出其執(zhí)行結(jié)果,該程序分析下列程序,指出其執(zhí)行結(jié)果,該程序命名為命名為exam.c,exam.c,經(jīng)編譯連接后生成的可執(zhí)行程序為經(jīng)編譯連接后生成的可執(zhí)行程序為exam.exeexam.exe #include #include main (int argc , char * argv ) int i=0; printf(“argc=%dn”,argc); while (argc =1) printf(“n參數(shù)參數(shù)%d:%s”,i,*argv); i+; argc-;argv+; 下一頁下一頁上一頁上一頁輸出結(jié)果:輸出結(jié)果: argc=4argc=4 參數(shù)參數(shù)0 0:examex
53、am 參數(shù)參數(shù)1 1:Turbo_cTurbo_c 參數(shù)參數(shù)2 2:C+C+ 參數(shù)參數(shù)3 3:VcVc 程序開始運行后,系統(tǒng)將命令行中字符串個數(shù)程序開始運行后,系統(tǒng)將命令行中字符串個數(shù)送送argc,argc,將四個字符串實參:將四個字符串實參:examexam、Turbo_cTurbo_c、C+C+、VcVc的首地址分別傳給字符指針數(shù)組元素的首地址分別傳給字符指針數(shù)組元素argv0argv0、argv1argv1、argv2argv2、argv3argv3。 若運行該程序時的命令行輸入的是:若運行該程序時的命令行輸入的是: exam Turbo_c C+ Vcexam Turbo_c C+ V
54、c上一頁上一頁返回6.6 變量的存儲屬性概述v變量是對程序中數(shù)據(jù)的存儲空間的抽象內(nèi)存.main() int a; a=10; printf(“%d”,a);編譯或函數(shù)調(diào)用時為其分配內(nèi)存單元1020002001程序中使用變量名對內(nèi)存操作v變量的屬性l數(shù)據(jù)類型:變量所持有的數(shù)據(jù)的性質(zhì)(操作屬性)l存儲屬性u存儲器類型:寄存器、靜態(tài)存儲區(qū)、動態(tài)存儲區(qū)u生存期:變量在某一時刻存在-靜態(tài)變量與動態(tài)變量u作用域:變量在某區(qū)域內(nèi)有效-局部變量與全局變量v變量的存儲類型lauto -自動型lregister-寄存器型lstatic -靜態(tài)型lextern -外部型v變量定義格式: 存儲類型 數(shù)據(jù)類型 變量表;
55、概述v變量是對程序中數(shù)據(jù)的存儲空間的抽象如: int sum; auto int a,b,c; register int i; static float x,y;局部變量與全局變量v局部變量-內(nèi)部變量l定義:在函數(shù)內(nèi)定義,只在本函數(shù)內(nèi)有效l說明:umain中定義的變量只在main中有效u不同函數(shù)中同名變量,占不同內(nèi)存單元u形參屬于局部變量u可定義在復(fù)合語句中有效的變量u局部變量可用存儲類型:auto register static (默認(rèn)為auto)float f1(int a) int b,c; .char f2(int x,int y) int i,j; main() int m,n; .
56、a,b,c有效x,y,i,j有效m,n有效例 不同函數(shù)中同名變量main() int a,b; a=3; b=4; printf(main:a=%d,b=%dn,a,b); sub(); printf(main:a=%d,b=%dn,a,b);sub() int a,b; a=6; b=7; printf(sub:a=%d,b=%dn,a,b);例 復(fù)合語句中變量#define N 5main() int i; int aN=1,2,3,4,5; for(i=0;iN/2;i+) int temp;temp=ai;ai=aN-i-1;aN-i-1=temp; for(i=0;iN;i+) pr
57、intf(%d ,ai);運行結(jié)果:5 4 3 2 1例 復(fù)合語句中變量#define N 5main() int i; int aN=1,2,3,4,5; for(i=0;iN/2;i+) int temp;temp=ai;ai=aN-i-1;aN-i-1=temp; for(i=0;il外部變量說明: extern 數(shù)據(jù)類型 變量表;l外部變量定義與外部變量說明不同l若外部變量與局部變量同名,則外部變量被屏蔽l外部變量可用存儲類型:缺省 或 staticfloat max,min;float average(float array, int n) int i; float sum=arra
58、y0; max=min=array0; for(i=1;imax) max=arrayi; else if(arrayiy?x:y; return(z);main() extern int a,b; printf(max=%d,max(a,b);int a=13,b=-8;運行結(jié)果:max=13extern int a,b;int max() int z; z=ab?a:b; return(z);main() printf(max=%d,max();int a=13,b=-8;/*ch7_17.c*/int a=3,b=5;max(int a, int b) int c; c=ab?a:b;
59、return(c);main() int a=8; printf(max=%d,max(a,b);例 外部變量與局部變量運行結(jié)果:max=8int i;main() void prt(); for(i=0;i5;i+) prt();void prt() for(i=0;i5;i+) printf(“%c”,*); printf(“n”);例 外部變量副作用運行結(jié)果:*動態(tài)變量與靜態(tài)變量v存儲方式l靜態(tài)存儲:程序運行期間分配固定存儲空間l動態(tài)存儲:程序運行期間根據(jù)需要動態(tài)分配存儲空間v內(nèi)存用戶區(qū)程序區(qū)靜態(tài)存儲區(qū)動態(tài)存儲區(qū)全局變量、局部靜態(tài)變量形參變量局部動態(tài)變量(auto register)函數(shù)
60、調(diào)用現(xiàn)場保護和返回地址等v生存期l靜態(tài)變量:從程序開始執(zhí)行到程序結(jié)束l動態(tài)變量:從包含該變量定義的函數(shù)開始執(zhí)行至函數(shù)執(zhí)行結(jié)束1 1、autoauto變量變量 函數(shù)內(nèi)部無函數(shù)內(nèi)部無staticstatic聲明的局部量均為動態(tài)存儲類別,被分配在動態(tài)區(qū)。聲明的局部量均為動態(tài)存儲類別,被分配在動態(tài)區(qū)。存儲類別為自動時,聲明符存儲類別為自動時,聲明符autoauto可省;自動變量被分配在動態(tài)區(qū),可省;自動變量被分配在動態(tài)區(qū),未賦初值時,其值未定義,每次調(diào)用重新賦值。未賦初值時,其值未定義,每次調(diào)用重新賦值。 int f(int a) int f(int a) auto int b,c=3; / auto int b,c=3; /* *定義定義b b、c c為自動變量為自動變量* */ / 又如:又如:auto int b,c=3; auto int b,c=3; int b,c=3; int b,c=3; / /* *兩者等價兩者等價* */ /2 2、用、用static static 聲明局部變量聲明局部變量 若希望函數(shù)若希望函數(shù)調(diào)用結(jié)束后,其值不消失調(diào)用結(jié)束后,其值不消失,下次調(diào)用函數(shù)時繼續(xù)使用,下次調(diào)
溫馨提示
- 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)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 服務(wù)提供商銷售協(xié)議
- 國防生培養(yǎng)協(xié)議書
- 2024版?zhèn)€人二手車輛轉(zhuǎn)讓合同范本
- 房屋拆遷合同糾紛處理辦法
- 聘用合同范本簡單2024年
- 代理證券買賣協(xié)議書范本
- 正規(guī)的食堂承包合同范本
- 老人結(jié)伴旅游免責(zé)協(xié)議書
- 施工分包合同書
- 勞務(wù)合同書范本匯編
- 食品委托配送運輸合同范本共
- 駐村干部應(yīng)知應(yīng)會試題附有答案
- 教科版小學(xué)科學(xué)四上《3.3用橡皮筋驅(qū)動小車》課件
- 主題三:紅色之美 第12課《置死地而后生-飛奪瀘定橋》 課件
- 2023年高考生物重點、難點、熱點暨命題趨勢和復(fù)習(xí)指導(dǎo)課件44
- 湖北省大冶市紅峰礦區(qū)建筑石料用(熔劑用)石灰?guī)r礦礦產(chǎn)資源開發(fā)利用與生態(tài)復(fù)綠方案
- 湖北省陽新縣富池鎮(zhèn)曹家山礦區(qū)建筑石料用石灰?guī)r礦礦產(chǎn)資源開發(fā)利用及生態(tài)復(fù)綠方案
- 測井原理及方法
- 建筑施工承插型盤扣式鋼管支架安全技術(shù)標(biāo)準(zhǔn)
- 土地管理法培訓(xùn)課件
- 當(dāng)代媒介素養(yǎng) 課件 第六章 報刊媒介素養(yǎng)
評論
0/150
提交評論