C語言程序設計經典教程課件_第1頁
C語言程序設計經典教程課件_第2頁
C語言程序設計經典教程課件_第3頁
C語言程序設計經典教程課件_第4頁
C語言程序設計經典教程課件_第5頁
已閱讀5頁,還剩43頁未讀 繼續免費閱讀

下載本文檔

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

文檔簡介

1第七章函數主要內容7.1概述7.2函數定義7.3函數參數、函數調用和函數值的返回7.4函數的嵌套與遞歸調用7.5變量的作用域1第七章函數主要內容2重點函數的定義和調用;函數參數(數組名作為函數的參數);局部變量。2重點函數的定義和調用;37.1

概述例7.1

main() { PrintStar(); PrintMessage(); PrintStar(); } PrintStar() { printf("**********\n"); } PrintMessage() { printf("Hello\n"); }PrintStar函數PrintMessage函數main函數主函數兩個自定義函數**********Hello**********37.1概述例7.1PrintStar函數PrintMes4說明:一個源程序文件由一個或多個函數組成。一個源程序文件是一個編譯單位。即以源程序單位進行編譯。一個C程序由一個或多個源程序文件組成。便于調試,提高開發效率。C程序總是從main函數開始執行,在調用完其他函數后返回到main函數。從main函數開始執行,不管將其寫在前面、中間或最后。main函數是系統定義的。所有函數都是平行定義的(即不可以嵌套定義),但可以嵌套調用。4說明:一個源程序文件由一個或多個函數組成。5從用戶角度看,C語言函數分為兩種:庫函數是系統提供的已設計好的函數,只要指定了要調用函數所在的庫文件,就可以直接調用了。用戶自定義函數是用戶自己編寫的用來解決具體問題的函數。從函數的形式看,函數分為兩類:無參函數不需要向函數傳遞參數。有參函數需要向函數傳遞必要的參數。本章將要詳細介紹的是用戶自定義函數。5從用戶角度看,C語言函數分為兩種:67.2函數定義函數定義的一般形式 類型符函數名(形式參數說明表) { 說明部分 語句部分

}函數頭(首部)函數體intadd(intx,inty){ intsum; sum=x+y; returnsum;}完整的函數定義無參函數定義空函數定義intread(){ intx; scanf("%d",&x); returnx;}

dummy(){}67.2函數定義函數定義的一般形式函數頭(首部)函數體77.3函數參數、函數值(返回值)及函數調用7.3.1函數的參數:[例7.2]main(){ inta=15,b=20,c; c=max(a+10,b); printf("Max=%d",c);}intmax(intx,inty){ intz; z=x>y?x:y; returnz;}

main函數max函數形參實參15a20bczxy2520252577.3函數參數、函數值(返回值)及函數調用7.3.1函8說明:定義函數時,形參是變量,必須指定類型。形參變量需要的存儲單元是在函數被調用時才給它分配,函數結束時予以釋放。實參與形參在個數和類型上應一一對應。實參可以是常量、變量或表達式。但變量和表達式要有確定的值。如當a=10時:c=max(7,8); /*ok*/c=max(a,2*4); /*ok*/c=max(a,b); /*error,b沒有確定的值*/C語言中,參數的傳遞是"值傳遞",即單向傳遞。數據只能由實參傳送給形參,而不由形參傳回給實參。8說明:97.3.2函數的返回值 通常,在調用一個函數時,都希望被調函數能返回一個確定的值。這就是函數的返回值。函數的返回值是通過返回語句return實現的,返回語句的形式為:

return;或return表達式;前一種形式,函數返回值是不確定的,這時調用者一般對返回值不感興趣,同時將函數說明成void類型。后一種形式,函數要把"表達式"的值返回給調用者。97.3.2函數的返回值10說明:如果要從被調函數帶回一個值,被調函數中必須要有"return表達式"語句。函數中可以有多個return語句,執行到哪個,哪個就起作用且立即返回調用函數。例如:intmax(intx,inty){ if(x>y) returnx; else returny;}10說明:11函數的返回值要有一個確定的類型,應該在定義函數時指定。 如:intmax(x,y) /*max函數值為整型*/charletter(intasc)/*letter函數值為字符型*/longfact(intn) /*fact函數值為長整型*/為了明確函數不返回值,可用關鍵字"void"定義函數。如:voidadd(intx,inty){ printf("Sumis%d",x+y);}11函數的返回值要有一個確定的類型,應該在定義函數時指定。12例7.3floatpower(floatx,intn){ floaty=1; inti; for(i=1;i<=n;i++) y*=x; returny;}main(){ floata=2.5,c; intb=3; c=power(a,b); printf("%f\n",c);}12例7.3floatpower(floatx,int137.3.3函數的調用函數調用的一般形式函數名(實參表)若是調用無參函數,則實參表可沒有,但括號不可省。若實參表包含多個實參,則各參數之間用逗號隔開。實參與形參的個數應相等,類型應一致。實參與形參按順序對應,一一傳遞數據。如:

p=power(2.5,4); /*ok*/ q=power(2.5,3.8); /*error*/ s=power(2.5); /*error*/ t=power(5,3); /*ok*/137.3.3函數的調用函數調用的一般形式14函數調用的方式1.函數語句:即把函數調用作為一個語句。

如:

PrintStar(); printf("***********");這時不要求函數帶回值,只要求完成一定的操作,通常將函數字義為"void"類型。2.函數表達式:函數出現在可以寫表達式的地方,此時需要的是函數的值。

如:c=2*max(a,b);printf("%d",max(a,b));14函數調用的方式15對被調函數的聲明

main() {inta=10,b=20,c;c=max(a,b); printf("%d\n",c); } intmax(intx,inty) {returnx>y?x:y; }怎樣使這些信息正確呢?C編譯系統假定:

1、函數名:max2、函數類型:int根據掃描得知:

3、有兩個參數

4、每一個參數的類型均為int該函數與已知信息相符。floatfloatfloatfloat%f由于類型的變化,使該函數與已知信息不相符。這句有錯誤!float對被調函數的聲明15對被調函數的聲明C編譯系統假定:該函數與已知信息相符。16函數聲明有三種格式:格式1:函數類型函數名(形參說明表);格式2:函數類型函數名(形參類型表);格式3:函數類型函數名(); 如:intmax(intx,inty);intmax(int,int);intmax();函數原型16函數聲明有三種格式:函數原型17例7.4函數聲明#include<stdio.h>main(){

floatmax(floatx,floaty); floata=10,b=20,c; c=max(a,b); printf("%f\n",c);}floatmax(floatx,floaty){returnx>y?x:y;}17例7.4函數聲明#include<stdio.h>18不必函數聲明的情況:當函數定義出現在主調函數之前,可不必函數聲明。函數定義包括了函數聲明。 例7.4.1如果被調函數的函數值為int類型,也可以不必函數聲明。

例7.218不必函數聲明的情況:19函數定義在主函數之前,可無函數聲明例7.4.1#include<stdio.h>floatmax(floatx,floaty){returnx>y?x:y;}main(){ floata=10,b=20,c; c=max(a,b); printf("%f\n",c);}19函數定義在主函數之前,可無函數聲明例7.4.120被調函數的函數值為int類型,可無函數聲明。例7.2

main(){ inta=15,b=20,c; c=max(a+10,b); printf("Max=%d",c);}intmax(intx,inty){ intz; z=x>y?x:y; returnz;}20被調函數的函數值為int類型,可無函數聲明。例7.2217.3.4數組作函數參數函數實參可以為變量。數組元素同樣是變量(下標變量),也可以作函數的實參。此外,數組名也可以作函數的參數,傳遞整個數組。數組元素作函數的實參數組元素作函數實參的用法與普通變量的用法一致,是單向傳遞。[例7.5]找出數組中的最大值217.3.4數組作函數參數函數實參可以為變量。數組元素22[例7.5]找出數組中的最大值intmax(intx,inty){ returnx>y?x:y;}main(){ inta[]={8,7,55,23,49}; inti,m; m=a[0]; for(i=1;i<5;i++) m=max(m,a[i]); /*數組元素作實參*/ printf("Max=%d\n",m);}22[例7.5]找出數組中的最大值intmax(int23練習7.5:打印一批數中的素數。判斷是否是素數由函數(PrimeNumber)完成。#include<stdio.h>#include<math.h>intPrimeNumber(intx){ inti; for(i=2;i<=sqrt(x);i++) if(x%i==0)return0; return1;}main(){ inta[]={15,17,19,21,23}; inti; for(i=0;i<5;i++) if(PrimeNumber(a[i])==1) printf("%d\t",a[i]); printf("\n");}23練習7.5:打印一批數中的素數。判斷是否是素數由函數(24數組名作函數參數當數組名作參數時,傳遞的是整個數組。按照實參與形參的對應要求,當實參為數組名時,形參必須定義為與實參是同類型的數組。[例7.6]:找出數組中的最大值

intarray_max(intx[5]){……} main() { inta[]={8,7,55,23,49}; …… max=array_max(a); …… }形參數組可以不指定大小。為了能正確使用數組元素,再增加一個參數用來存放數組元素的個數。24數組名作函數參數形參數組可以不指定大小。25[例7.6]找出數組中的最大值在主函數中告知找哪個數組中的最大,找最大由函數完成。intarray_max(intx[5]) /*數組名作形參*/{ inti,m=x[0]; for(i=1;i<5;i++) if(m<x[i])m=x[i]; returnm;}main(){ inta[]={8,7,55,23,49}; intmax; max=array_max(a); /*數組名作實參*/ printf("Max=%d\n",m);}25[例7.6]找出數組中的最大值在主函數中告知找哪個數組中26練習7.6:編寫一個函數,求數組元素之和。一般情況下,當函數被調用時,需要為形參變量分配存儲單元。但當數組名作參數時,并不給形參數組分配存儲單元,而是實現"換名操作"。例7.6的運行分析:intarray_max(intx[],intn){…}main(){inta[]={8,7,55,23,49};…max=array_max(a);…}a87552349x26練習7.6:編寫一個函數,求數組元素之和。intarr27練習7.6編寫一個函數,用來求給定數組的元素之和。intArrSum(intx[]){ inti,s=0; for(i=0;i<5;i++) s+=x[i]; returns;}main(){ inta[]={2,4,6,8,10}; printf("Sym=%d\n",ArrSum(a));}27練習7.6編寫一個函數,用來求給定數組的元素之和。i287.4函數的嵌套與遞歸調用例7.7voidprint_star();voidprint_hello();main(){ print_star(); print_hello(); print_star();}voidprint_star(){printf("**********\n");}voidprint_hello(){printf("Hello\n");}嵌套調用287.4函數的嵌套與遞歸調用例7.7嵌套調用29遞歸調用在調用一個函數的過程中又出現直接或間接地調用該函數本身,稱為函數的遞歸調用。C語言的特點之一就在于允許函數的遞歸調用。例如:intfun(intx){ inty,z; …… z=fun(y); …… returnz-10;}

從遞歸調用的形式上看,函數會無終止地調用自己,這種情況是我們所不希望的。因此,在定義遞歸函數時還要有終止條件,使遞歸調用在條件不滿足時不再繼續。29遞歸調用在調用一個函數的過程中又出現直接或間接地調用該函30[例7.8]用遞歸方法求xn。分析: 求解過程:24→23→22→21→20運行過程分析:30[例7.8]用遞歸方法求xn。31[例7.8]用遞歸方法求x^n。floatPow(floatx,intn){ floatp; if(x==1||n==0) p=1.0; /*終止條件*/ elsep=x*Pow(x,n-1); returnp;}main(){ printf("2的4次冪=%f\n",Pow(2,4));}31[例7.8]用遞歸方法求x^n。floatPow(f32練習7.8:計算n!的數學定義為:

請編寫遞歸函數fact()求n!。32練習7.8:計算n!的數學定義為:33練習7.8:用遞歸函數求n!longfact(intn){ longf; if(n==0||n==1)f=1; else f=n*fact(n-1); returnf;}main(){ inta=5; printf("%d!=%ld\n",a,fact(a));}33練習7.8:用遞歸函數求n!longfact(int347.5

變量的作用域charch;doublefun2(charc){ floatb; …… ch=c;}intx;main(){ intm,n; ……}在函數內部說明的變量是局部變量。作用域:自說明位置起至函數結束止。在函數外部說明的變量是全局變量。作用域:自說明位置起至文件結束止。cbm,nchx347.5變量的作用域charch;在函數內部說明的變量35在定義一個變量時,除了指定其數據類型外,還可以指定其存儲類別。C語言中用四個關鍵字來表示存儲類別:auto————自動的register———寄存器的static ———

靜態的extern———

外部的局部變量全局變量35在定義一個變量時,除了指定其數據類型外,還可以指定其存儲367.8.1局部變量自動變量(auto)intf(inta){ autointb,c=3; ……}自動變量在內存的動態存儲區分配:當函數(或分程序)執行時為自動變量分配存儲空間;當函數(或分程序)結束時釋放自動變量所占的存儲空間。auto關鍵字可以省略。367.8.1局部變量自動變量(auto)37寄存器變量(register)intf(inta){ registerinti; ……}

寄存器變量存在于CPU的寄存器中:當函數(或分程序)執行時為寄存器變量分配寄存器;當函數(或分程序)結束時釋放寄存器變量所占用的寄存器。37寄存器變量(register)38自動變量與寄存器變量之間的區別自動變量main(){ ints=0,i; for(i=1;i<=3;i++)s=s+i; ……}寄存器變量main(){ registerints=0,i; for(i=1;i<=3;i++)s=s+i; ……}CPU運算器寄存器si內存0CPU運算器內存si寄存器運行分析運行分析1131011201312寄存器變量的使用可以減少內存與CPU之間的數據交換,從而提高程序執行的效率。38自動變量與寄存器變量之間的區別CPU運寄存器si內存0C39靜態的局部變量(static)如:staticintx;

靜態的局部變量在內存的靜態存儲區分配。靜態存儲區具有如下性質:在編譯時即分配存儲空間;當程序執行結束后,由操作系統把應用程序撤消時才被釋放。存儲在靜態區的變量,未初始化時為0。

雖然它在整個程序的運行期間總是存在的,但由于它是局部變量,還要受作用域的限制。這與其所在的函數無關39靜態的局部變量(static)這與其所在的函數無關40[例7.9]靜態變量與動態變量的比較voidinc(intz){ staticintx=0; autointy=0; x++; y++;z++; printf("%d,%d,%d\n",x,y,z);}main(){intp=5; inc(p); inc(p);}運行分析問題函數動態區靜態區mainincx00yzp55116運行結果:1,1,62,1,60yz5162此處加一句:printf("%d",x);可以嗎?40[例7.9]靜態變量與動態變量的比較voidinc(41全局(程)變量,它是在函數外部定義的。存儲在靜態區,它的內存分配與釋放是由系統完成的。全局變量未初始化時,其初值為0。全局變量的作用域是從定義它的位置開始,一直到本文件結束。[例7.10]在程序中使用全局變量求1!+2!+……+5!7.8.2全局變量41全局(程)變量,它是在函數外部定義的。存儲在靜態區,它的42[例7.10]在程序中使用全局變量求1!+2!+……+5!intp=1;voidfact(intn){ p=p*n;}main(){ inti,s; for(s=0,i=1;i<=5;i++) { fact(i); s+=p; } printf("1!+2!+……+5!=%d\n",s);}42[例7.10]在程序中使用全局變量求1!+2!+……+43全局變量的使用全局變量雖然增加了函數傳遞數據的渠道,但它的使用使函數的通用性降低。由于全局變量在程序執行期間一直占用內存空間,增加了內存開銷。結論不在必要時,最好不使用全局變量。

43全局變量的使用全局變量雖然增加了函數傳遞數據的渠道,但它441.下列程序的運行結果是5和8,還是8和5? 說明為什么。voidswap(intx,inty){ intt; t=x; x=y; y=t;}main(){ inta=5,b=8; swap(a,b); printf("%d,%d",a,b);}小測試441.下列程序的運行結果是5和8,還是8和5?小測試452.寫出下列程序的輸出結果。voidfun(int,i

溫馨提示

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

評論

0/150

提交評論