




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第七章函數第七章函數1該章的學習內容學點什么哪?掌握函數原型(prototype)及其,函數定義和函數原型說明的方法及二者的區別。掌握函數的參數傳遞方式與函數調用方法。理解掌握變量的作用域和存儲類的概念。該章的學習內容學點什么哪?掌握函數原型(prototype)21.通過C語言的學習,牢固樹立起函數的概念,及其使用規則。2.理解函數的作用域及其存儲類及其自動變量與靜態局部變量在應用中的區別。*3.在實際應用中,學習和體會采用結構化設計方法(模塊化)解決問題的思想。本章的學習難點1.通過C語言的學習,牢固樹立起函數的概念,及其使用規則。3本章目錄函數1.1.函數有關概念及其分類1.2.函數的定義1.3.函數的返回值1.4.函數的調用與參數傳遞1.5.函數原型的說明*宏定義變量的作用域和存儲類*模塊化程序設計方法*應用設計實例多文件方式組織的程序本章目錄函數4概述
一個較大的程序一般應分為若干個程序模塊,每一個模塊用來實現一定的功能。所有的高級語言中都有子程序這個概念,用子程序來實現模塊功能。在C語言中,子程序的作用是由函數來完成的。一個C程序可由一個主函數和若干個函數構成。由主函數調用其它函數,其它函數也可以互相調用。同一個函數可以被一個或多個函數調用任意多次。
概述一個較大的程序一般應分為若干個程序模塊,5程序設計中,常將一些常用的功能模塊編寫成函數,放在函數庫中供公共選用。要善于用函數,以減少重復編程的工作量。C語言提倡把一個大問題劃分成許多個小塊,每一小塊編制一個函數。這樣C程序是由許多小函數而不是由少量大函數構成。這樣作的好處:各部分充分獨立,任務單一,便于書寫和調試。有些小函數還可以作為構件,被別的程序利用。概述程序設計中,常將一些常用的功能模塊編寫成函數,6C程序工程源程序文件1源程序文件2源程序文件3編譯預處理命令全局變量聲明函數1函數n…函數首部函數體局部變量聲明執行語句C程序的基本結構C程序工程源程序文件1源程序文件2源程序文件3編譯預處理命令7mainabcdeifghegh程序中函數調用示意圖mainabcdeifghegh程序中函數調用示意圖8基本思想:將一個大的程序按功能分割成一些小模塊.特點:各模塊相對獨立、功能單一、結構清晰、接口簡單控制了程序設計的復雜性提高元件的可靠性縮短開發周期避免程序開發的重復勞動易于維護和功能擴充開發方法:
自上向下,逐步分解,分而治之模塊化程序設計基本思想:將一個大的程序按功能分割成一些小模塊.模塊化程序設9C是模塊化程序設計語言規則必須有且只能有一個名為main的主函數C程序的執行總是從main函數開始,在main中結束。函數不能嵌套定義,可以嵌套調用C是模塊化程序設計語言規則必須有且只能有一個名為main的主10函數的基本概念(1)
project——工程:是由一個或多個C程序源文件組成。一個源程序是由一個或多個函數組成。一個源程序是一個編譯單位,即以源程序為單位進行編譯,而不是以函數為單位進行編譯。其擴展名為.h或.c。(3)C程序的執行從main()函數開始。沒有main()函數的程序,不能執行。調用其他函數后流程回到main函數,在main函數結束整個程序運行。main函數是系統定義的。(4)主函數可以調用任意子函數,而子函數不能調用主函數。
子函數的地位是平等的,相互獨立,相互無從屬關系,可以相互調用。子函數可以直接或間接地自己調用自己,即遞歸調用。(2)C語言程序源文件由函數組成函數的概念是C語言結構程序設計思想的體現。主函數:包括一個且僅有一個——main()。其他函數:可以有,也可以沒有,可以有一個,也可以有多個。函數的基本概念(1)project——工程:是由一個11使用庫函數應注意:1、函數功能2、函數參數的數目和順序,及各參數意義和類型3、函數返回值意義和類型4、需要使用的包含文件標準函數(庫函數):由系統提供:printf、scanf、getchar、putchar等用戶自定義函數:由用戶按需要寫的函數。從用戶角度看:函數的分類(1)使用庫函數應注意:從用戶角度看:函數的分類(1)12無參函數:在調用無參函數時,主調函數并不將數據送給被調函數,一般用來執行指定的一組操作。無參函數可以帶回或不帶回函數值,但一般以不帶回函數值居多。有參函數:在調用函數時,在主調函數和被調函數之間有參數傳遞,也就是說主調函數可以將數據傳給被調函數使用,被調用函數中的數據也可以帶回來供主調函數使用。從函數的形式看:max(intx,inty){…..}max(){…..}無參函數:在調用無參函數時,主調函數并不將數據送給被調函數13有返回值函數:此類函數被調用執行完后將向調用者返回一個執行結果,稱為函數返回值。必須在函數定義和函數說明中明確返回值的類型。無返回值函數:此類函數用于完成某項特定的處理任務,執行完成后不向調用者返回函數值。空類型的說明符為“void”從函數的返回值形式看:intmax(){return表達式;}voidmax(){……..}有返回值函數:此類函數被調用執行完后將向調用者返回一個執行結14函數的定義(1)傳統風格函數定義:
類型
函數名(形參表列)形參說明{
說明部分 語句}形參表列是用逗號分隔的形參,形參又稱為形式參數、啞元、虛參、虛擬參數。在形參說明中,說明形參表中每個形參的類型。類型:函數類型,用來說明本函數返回值的類型。當函數返回值是整型或不要求返回值時,可省略類型說明。無返回值可用“空類型”—void函數定義時的參數稱為行參;函數調用時的參數稱為實參。函數的定義(1)傳統風格函數定義:形參表列是用逗號分15(2)函數的現代定義方式類型函數名(形參說明表列){說明部分語句}函數體 將形參說明包含到形參列表中,即在列出形參的同時,說明形參類型。形參列表:類型參數1,類型參數2,…,類型參數n傳統定義舉例現代定義舉例intadd(x,y)intadd(intx,inty)intx,y;{……{……}}(2)函數的現代定義方式類型函數名(形參說明表列)函數體161.無參函數類型標識符函數名(){說明部分語句}類型標識符:表示返回值類型7.2.1函數的定義Hello(){printf("Hello,world\n");}例如:定義一個函數說明:這里,只把main改為Hello作為函數名,其余不變。Hello函數是一個無參函數,當被其它函數調用時,輸出Helloworld字符串。1.無參函數類型標識符函數名()7.2.1函17類型標識符函數名(形參表列){說明部分語句}2.有參函數例:求二數之最大值
intmax(intx,inty){intz;
z=x>y?x:y;return(z);}注意:出現return,語句,返回值一般與函數類型一致。類型標識符函數名(形參表列)18合法標識符函數返回值類型缺省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”);}合法標識符函數返回值類型函數體函數類型函數名(形參193.可以有“空函數”
類型說明符函數名(){}例如:dummy(){}調用此函數時,什么工作也不做,沒有任何實際作用。在主調函數中寫上“dummy();”表明“這里要調用一個函數”,而現在這個函數沒有起作用,等以后擴充函數功能時補充上。3.可以有“空函數”20函數定義說明(1)一個源程序文件由一個或多個函數組成。一個源程序文件是一個編譯單位,即以源程序為單位進行編譯,而不是以函數為單位進行編譯。(2)一個C程序由一個或多個源程序文件組成。對較大的程序,一般不希望全放在一個文件中,而將函數和其他內容(如預定義)分別放在若干個源文件中,再由若干源文件組成一個C程序。這樣可以分別編寫、分別編譯,提高調度效率。一個源文件可以為多個C程序公用。函數定義說明(1)一個源程序文件由一個或多個函數組成。一個21函數定義說明(3)C程序的執行從main函數開始,調用其他函數后流程回到main函數,在main函數中結束整個程序的運行。main函數是系統定義的。(4)所有函數都是平行的,即在定義函數時是互相獨立的,一個函數并不從屬于另一函數,即函數不能嵌套定義,函數間可以互相調用,但不能調用main函數。函數定義說明(3)C程序的執行從main函數開始,調用其他22程序舉例1定義求兩個整數和的函數。intadd(intx,inty){intz;z=x+y;return(z);}程序舉例1定義求兩個整數和的函數。intadd(int23intmax(intx1,intx2,intx3){intmax;if(x1>x2)max=x1;elsemax=x2;if(max<x3)max=x3;
return(max);
}
編寫函數,求三個整型參數的最大值。
程序舉例2/*定義函數的返回值類型,函數名,形參*//*通過比較得到三個數的最大值放到max中*//*返回運算結果*/intmax(intx1,intx2,intx3)編24函數的返回值功能將被調函數中的結果值返回給主調函數。語句return(返回值表達式)或return表達式;或return;舉例intadd(intx,inty){intz;z=x+y;return(z);}函數的返回值功能將被調函數中的結果值返回給主調函數。語句re25
(1)函數的返回值是通過函數中的return語句獲得的。return語句將被調用函數中的一個確定值帶回主調函數中去。如果需要從被調用函數帶回一個函數值(供主調函數使用),被調用函數中必須包含return語句。如果不需要從被調用函數帶回函數值,可以不要return語句。一個函數中可以有一個以上的return語句,執行到哪一個return語句,哪一個語句起作用。return語句后面的括弧也可以不要,如returnz;它與“return(z);”等價。說明:說明:26例如,max(intx,inty){intz;z=x>y?x∶y;return(z);}
函數max可以改寫如下:max(intx,inty){return(x>y?x∶y);}(2)return后面的值可以是一個表達式這樣的函數體更為簡短,只用一個return語句就把求值和返回都解決了。例如,函數max可以改寫如下:(2)return后面的值可27(3)函數值的類型。既然函數有返回值,這個值當然應屬于某一個確定的類型,應當在定義函數時指定函數值的類型。C語言規定,凡不加類型說明的函數,一律自動按整型處理。
在定義函數時對函數值說明的類型一般應該和return語句中的表達式類型一致。例如,例2中用隱含方式指定max函數值為整型,而變量z也被指定為整型,通過return語句把z的值作為max的函數值,由max帶回主調函數。z的類型與max函數的類型是一致的,是正確的。(4)若無return語句,遇到函數結束的“}”時,自動返回調用函數(3)函數值的類型。既然函數有返回值,這個值當然應屬于某一28
(5)如果函數值的類型和return語句中表達式的值不一致,則以函數類型為準。對數值型數據,可以自動進行類型轉換。即函數類型決定返回值的類型。main(){floata,b;intc;scanf(“%f,%f,”&a,&b); max(floatx,floaty);c=max(a,b);printf("Maxis%d\n",c);}max(floatx,floaty){floatz;/*z為實型變量*/z=x>y?x∶y;return(z);}運行情況如下:1.5,2.5Maxis2(5)如果函數值的類型和return語句29printstar(){printf("**********");}main(){inta;a=printstar();printf("%d",a);}(6)無返回值的函數返回后帶回不確定值輸出:10voidprintstar(){printf("**********");}main(){inta;
a=printstar();printf("%d",a);}編譯錯誤!printstar()(6)無返回值的函數返回后帶回不確定30程序舉例2下面add函數的功能是求兩個參數的和,并將和值返回調用函數。函數中的錯誤是:voidadd(floata,floatb) {floatc;c=a+b;returnc;}voidadd(floata,floatb)floatadd(floata,floatb)程序舉例2下面add函數的功能是求兩個參數的和,并將317.3函數的調用函數調用的一般形式為
函數名(實參表列);
如果是調用無參函數,則“實參表列”可以沒有,但括弧不能省略。如果實參表列包含多個實參,則各參數間用逗號隔開。實參與形參的個數應相等,類型應一致。實參與形參按順序對應,一一傳遞數據。7.3函數的調用函數調用的一般形式為32函數調用方式調用方式函數調用語句函數表達式函數參數print_star(n);voidprint_star(intn){inti;for(i=1;i<=n;i++)printf("*");}x=max(a,b)+5;x=max(max(a,b),c);函數調用方式調用方式函數調用語句函數表達式函數參數prin33
1.函數語句把函數調用作為一個語句。如hello();這時不要求函數帶回值,只要求函數完成一定的操作。2.函數表達式函數出現在一個表達式中,這種表達式稱為函數表達式。這時要求函數帶回一個確定的值以參加表達式的運算。例如:c=2*max(a,b);函數max是表達式的一部分,它的值乘2再賦給c。3.函數參數函數調用作為一個函數的實參。例如:m=max(a,max(b,c));其中max(b,c)是一次函數調用,它的值作為max另一次調用的實參。m的值是a、b、c三者最大的。又如:printf(“%d”,max(a,b));也是把max(a,b)作為printf函數的一個參數。1.函數語句34調用函數的過程是:①為函數的所有形參分配內存單元。②計算各個實參表達式的值,一一對應的賦值給相應形參(若是無參函數,上述過程不執行)。③進入函數體,執行函數中的語句,實現函數的功能。④執行到return語句時,計算return語句中表達式的值(若是無返回值函數,本項不做),返回到主調函數。⑤釋放形參及本函數內的局部變量所占內存,繼續執行主調函數中的后繼語句。調用函數的過程是:35形式參數和實際參數在調用函數時,大多數情況下,主調函數和被調用函數之間有數據傳遞關系。這就是前面提到的有參函數。前面已提到:在定義函數時函數名后面括弧中的變量名稱為“形式參數”(簡稱“形參”),在主調函數中調用一個函數時,函數名后面括弧中的參數(可以是一個表達式)稱為“實際參數”(簡稱“實參”)。形式參數和實際參數在調用函數時,大多數情36參數傳遞主調函數向被調函數傳值的方式:賦值調用
把實參的值賦給形參。賦地址調用
把實參的地址付給形參。在被調函數中,用該地址訪問主調函數中的實參。實參形參調用返回單向值傳遞參數傳遞主調函數向被調函數傳值的方式:賦值調用實參形參調用返37C語言中,函數調用是值傳遞方式,即函數的實際參數和形式參數之間的數據傳遞方向是單向的,只能由實際參數傳遞給形式參數,而不能由形式參數傳遞給實際參數,是實際參數向形式參數單向賦值的關系。在內存中,形式參數與實際參數占用不同的內存單元。當調用函數時,給形式參數分配內存單元,將實際參數的值賦值給形式參數,調用后,形式參數單元釋放,實際參數仍保留調用前的值,形式參數值的變化不影響實際參數。函數參數及其傳遞方式C語言中,函數調用是值傳遞方式,即函數的實際參數和形式參數之38調用結束:35a:b:例5.6交換兩個數#include<stdio.h>main(){inta=3,b=5;printf(“a=%d,\tb=%d\n",a,b);printf("swapped:\n");
swap(a,b);printf(“a=%d,\tb=%d\n",a,b);}swap(intx,inty){inttemp;temp=x;x=y;y=temp;}35a:b:調用前:調用35x:y:35a:b:swap:temp35a:b:x:35y:353temp=xx=yy=temp調用結束:35a:b:例5.6交換兩個數35a:b:39程序舉例分析一下程序,寫出運行結果。#include<stdio.h>main(){inta=5,b=10;printf("a=%d,b=%d\n",a,b);fun(a,b); /*函數調用*/printf("a=%d,b=%d\n",a,b);}intfun(intx,inty)/*現代風格函數定義*/{x=3;y=3;return;}a=5,b=10a=5,b=10程序舉例分析一下程序,寫出運行結果。#include<s40
main(){inta,b,c;scanf("%d,%d",&a,&b);c=max(a,b);printf(“Maxis%d",c);}max(intx,inty)/*定義有參函數max*/{intz;z=x>y?x∶y;return(z);}運行情況如下:7,8Maxis8形參實參c=max(a,b);(main函數)(max函數)max(intx,inty){intz;z=x>y?x:y;return(z);}程序舉例形參實參c=max(a,b);(main函數)(max函41說明:實參必須有確定的值形參必須指定類型形參與實參類型一致,個數相同若形參與實參類型不一致,自動按形參類型轉換———函數調用轉換形參在函數被調用前不占內存;函數調用時為形參分配內存;調用結束,內存釋放說明:42例計算x的立方#include<stdio.h>floatcube(floatx){return(x*x*x);}main(){floata,product;printf("Pleaseinputvalueofa:");scanf("%f",&a);product=cube(a);printf(”Cubeof%.4fis%.4f\n",a,product);}xaproduct××××1.21.21.728程序舉例例計算x的立方#include<stdio.h>xap43在一個函數中調用另一函數(即被調用函數)需要具備哪些條件呢?(1)首先被調用的函數必須是已經存在的函數(是庫函數或用戶自己定義的函數)。(2)如果使用庫函數,一般還應該在本文件開頭用#include命令將調用有關庫函數時所需用到的信息“包含”到本文件中來。例如,#include<stdio.h>其中“stdio.h”是一個“頭文件”。在stdio.h文件中放了輸入輸出庫函數所用到的一些宏定義信息。如果不包含“stdio.h”文件中的信息,就無法使用輸入輸出庫中的函數。在一個函數中調用另一函數(即被調用函數)44(3)如果使用用戶自己定義的函數,而且該函數與調用它的函數(即主調函數)在同一個文件中,一般還應該在主調函數中對被調用的函數作聲明,即向編譯系統聲明將要調用此函數,并將有關信息通知編譯系統。例:對被調用的函數作聲明。floatadd(floatx,floaty);/*對被調用函數的聲明*/main(){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);}
(3)如果使用用戶自己定義的函數,而且該45注意:對函數的“定義”和“聲明”不是一回事。“定義”是指對函數功能的確立,包括指定函數名,函數值類型、形參及其類型、函數體等,它是一個完整的、獨立的函數單位。
“聲明”的作用則是把函數的名字、函數類型以及形參的類型、個數和順序通知編譯系統,以便在調用該函數時系統按此進行對照檢查(例如函數名是否正確,實參與形參的類型和個數是否一致)。從程序中可以看到對函數的聲明與函數定義中的第1行(函數首部)基本上是相同的。因此可以簡單地照寫已定義的函數的首部,再加一個分號,就成為了對函數的“聲明”。其實,在函數聲明中也可以不寫形參名,而只寫形參的類型。如:floatadd(float,float);
注意:對函數的“定義”和“聲明”不是一回事。46
函數聲明又稱為函數原型(functionprototype)。作用:主要是利用它在程序的編譯階段對調用函數的合法性進行全面檢查。函數原型的一般形式為(1)函數類型函數名(參數類型1,參數類型2……);(2)函數類型函數名(參數類型1參數名1,參數類型2參數名2……);例如:(1)floatadd(float,float);(2)floatadd(floatx,floaty);函數聲明函數聲明又稱為函數原型(functionprotot47說明:(1)實際上,如果在函數調用之前,沒有對函數作聲明,則編譯系統會把笫一次遇到的該函數形式(函數定義或函數調用)作為函數的聲明,并將函數類型默認為int型。使用這種方法時,系統無法對參數的類型做檢查。若調用函數時參數使用不當,在編譯時也不會報錯。因此,為了程序清晰和安全,建議都加以聲明為好。(2)如果被調用函數的定義出現在主調函數之前,可以不必加以聲明。因為編譯系統已經先知道了已定義的函數類型,會根據函數首部提供的信息對函數的調用作正確性檢查。(3)如果被調用函數的定義出現在主調函數之后,必須加以聲明。因為編譯系統不知道此函數的存在。說明:48例函數說明舉例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型函數可不作函數說明/*ch7_5.c*/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();例函數說明舉例main()int型函數可不作函數說明/*49對于函數的位置:對于非int函數,調用單位的位置要在被調用單位在下面,否則編譯產生錯誤。解決方法是:在調用單位加上被調用函數的聲(說)明。voidf(){…}main(){…f();…}voidf(){…}main(){…f();…}voidf(){…}main(){voidf();…f();…}對于函數的位置:voidf()main()void50程序舉例4輸入兩個整數,求其中最大者并打印。#include<stdio.h>main(){inta,b,c;scanf("%d,%d",&a,&b);c=max(a,b); /*函數調用*/printf("max=%d",c);}intmax(intx,inty)/*現代風格函數定義*/{return();}x>y?x:y程序舉例4輸入兩個整數,求其中最大者并打印。#include51第七章函數第七章函數52該章的學習內容學點什么哪?掌握函數原型(prototype)及其,函數定義和函數原型說明的方法及二者的區別。掌握函數的參數傳遞方式與函數調用方法。理解掌握變量的作用域和存儲類的概念。該章的學習內容學點什么哪?掌握函數原型(prototype)531.通過C語言的學習,牢固樹立起函數的概念,及其使用規則。2.理解函數的作用域及其存儲類及其自動變量與靜態局部變量在應用中的區別。*3.在實際應用中,學習和體會采用結構化設計方法(模塊化)解決問題的思想。本章的學習難點1.通過C語言的學習,牢固樹立起函數的概念,及其使用規則。54本章目錄函數1.1.函數有關概念及其分類1.2.函數的定義1.3.函數的返回值1.4.函數的調用與參數傳遞1.5.函數原型的說明*宏定義變量的作用域和存儲類*模塊化程序設計方法*應用設計實例多文件方式組織的程序本章目錄函數55概述
一個較大的程序一般應分為若干個程序模塊,每一個模塊用來實現一定的功能。所有的高級語言中都有子程序這個概念,用子程序來實現模塊功能。在C語言中,子程序的作用是由函數來完成的。一個C程序可由一個主函數和若干個函數構成。由主函數調用其它函數,其它函數也可以互相調用。同一個函數可以被一個或多個函數調用任意多次。
概述一個較大的程序一般應分為若干個程序模塊,56程序設計中,常將一些常用的功能模塊編寫成函數,放在函數庫中供公共選用。要善于用函數,以減少重復編程的工作量。C語言提倡把一個大問題劃分成許多個小塊,每一小塊編制一個函數。這樣C程序是由許多小函數而不是由少量大函數構成。這樣作的好處:各部分充分獨立,任務單一,便于書寫和調試。有些小函數還可以作為構件,被別的程序利用。概述程序設計中,常將一些常用的功能模塊編寫成函數,57C程序工程源程序文件1源程序文件2源程序文件3編譯預處理命令全局變量聲明函數1函數n…函數首部函數體局部變量聲明執行語句C程序的基本結構C程序工程源程序文件1源程序文件2源程序文件3編譯預處理命令58mainabcdeifghegh程序中函數調用示意圖mainabcdeifghegh程序中函數調用示意圖59基本思想:將一個大的程序按功能分割成一些小模塊.特點:各模塊相對獨立、功能單一、結構清晰、接口簡單控制了程序設計的復雜性提高元件的可靠性縮短開發周期避免程序開發的重復勞動易于維護和功能擴充開發方法:
自上向下,逐步分解,分而治之模塊化程序設計基本思想:將一個大的程序按功能分割成一些小模塊.模塊化程序設60C是模塊化程序設計語言規則必須有且只能有一個名為main的主函數C程序的執行總是從main函數開始,在main中結束。函數不能嵌套定義,可以嵌套調用C是模塊化程序設計語言規則必須有且只能有一個名為main的主61函數的基本概念(1)
project——工程:是由一個或多個C程序源文件組成。一個源程序是由一個或多個函數組成。一個源程序是一個編譯單位,即以源程序為單位進行編譯,而不是以函數為單位進行編譯。其擴展名為.h或.c。(3)C程序的執行從main()函數開始。沒有main()函數的程序,不能執行。調用其他函數后流程回到main函數,在main函數結束整個程序運行。main函數是系統定義的。(4)主函數可以調用任意子函數,而子函數不能調用主函數。
子函數的地位是平等的,相互獨立,相互無從屬關系,可以相互調用。子函數可以直接或間接地自己調用自己,即遞歸調用。(2)C語言程序源文件由函數組成函數的概念是C語言結構程序設計思想的體現。主函數:包括一個且僅有一個——main()。其他函數:可以有,也可以沒有,可以有一個,也可以有多個。函數的基本概念(1)project——工程:是由一個62使用庫函數應注意:1、函數功能2、函數參數的數目和順序,及各參數意義和類型3、函數返回值意義和類型4、需要使用的包含文件標準函數(庫函數):由系統提供:printf、scanf、getchar、putchar等用戶自定義函數:由用戶按需要寫的函數。從用戶角度看:函數的分類(1)使用庫函數應注意:從用戶角度看:函數的分類(1)63無參函數:在調用無參函數時,主調函數并不將數據送給被調函數,一般用來執行指定的一組操作。無參函數可以帶回或不帶回函數值,但一般以不帶回函數值居多。有參函數:在調用函數時,在主調函數和被調函數之間有參數傳遞,也就是說主調函數可以將數據傳給被調函數使用,被調用函數中的數據也可以帶回來供主調函數使用。從函數的形式看:max(intx,inty){…..}max(){…..}無參函數:在調用無參函數時,主調函數并不將數據送給被調函數64有返回值函數:此類函數被調用執行完后將向調用者返回一個執行結果,稱為函數返回值。必須在函數定義和函數說明中明確返回值的類型。無返回值函數:此類函數用于完成某項特定的處理任務,執行完成后不向調用者返回函數值。空類型的說明符為“void”從函數的返回值形式看:intmax(){return表達式;}voidmax(){……..}有返回值函數:此類函數被調用執行完后將向調用者返回一個執行結65函數的定義(1)傳統風格函數定義:
類型
函數名(形參表列)形參說明{
說明部分 語句}形參表列是用逗號分隔的形參,形參又稱為形式參數、啞元、虛參、虛擬參數。在形參說明中,說明形參表中每個形參的類型。類型:函數類型,用來說明本函數返回值的類型。當函數返回值是整型或不要求返回值時,可省略類型說明。無返回值可用“空類型”—void函數定義時的參數稱為行參;函數調用時的參數稱為實參。函數的定義(1)傳統風格函數定義:形參表列是用逗號分66(2)函數的現代定義方式類型函數名(形參說明表列){說明部分語句}函數體 將形參說明包含到形參列表中,即在列出形參的同時,說明形參類型。形參列表:類型參數1,類型參數2,…,類型參數n傳統定義舉例現代定義舉例intadd(x,y)intadd(intx,inty)intx,y;{……{……}}(2)函數的現代定義方式類型函數名(形參說明表列)函數體671.無參函數類型標識符函數名(){說明部分語句}類型標識符:表示返回值類型7.2.1函數的定義Hello(){printf("Hello,world\n");}例如:定義一個函數說明:這里,只把main改為Hello作為函數名,其余不變。Hello函數是一個無參函數,當被其它函數調用時,輸出Helloworld字符串。1.無參函數類型標識符函數名()7.2.1函68類型標識符函數名(形參表列){說明部分語句}2.有參函數例:求二數之最大值
intmax(intx,inty){intz;
z=x>y?x:y;return(z);}注意:出現return,語句,返回值一般與函數類型一致。類型標識符函數名(形參表列)69合法標識符函數返回值類型缺省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”);}合法標識符函數返回值類型函數體函數類型函數名(形參703.可以有“空函數”
類型說明符函數名(){}例如:dummy(){}調用此函數時,什么工作也不做,沒有任何實際作用。在主調函數中寫上“dummy();”表明“這里要調用一個函數”,而現在這個函數沒有起作用,等以后擴充函數功能時補充上。3.可以有“空函數”71函數定義說明(1)一個源程序文件由一個或多個函數組成。一個源程序文件是一個編譯單位,即以源程序為單位進行編譯,而不是以函數為單位進行編譯。(2)一個C程序由一個或多個源程序文件組成。對較大的程序,一般不希望全放在一個文件中,而將函數和其他內容(如預定義)分別放在若干個源文件中,再由若干源文件組成一個C程序。這樣可以分別編寫、分別編譯,提高調度效率。一個源文件可以為多個C程序公用。函數定義說明(1)一個源程序文件由一個或多個函數組成。一個72函數定義說明(3)C程序的執行從main函數開始,調用其他函數后流程回到main函數,在main函數中結束整個程序的運行。main函數是系統定義的。(4)所有函數都是平行的,即在定義函數時是互相獨立的,一個函數并不從屬于另一函數,即函數不能嵌套定義,函數間可以互相調用,但不能調用main函數。函數定義說明(3)C程序的執行從main函數開始,調用其他73程序舉例1定義求兩個整數和的函數。intadd(intx,inty){intz;z=x+y;return(z);}程序舉例1定義求兩個整數和的函數。intadd(int74intmax(intx1,intx2,intx3){intmax;if(x1>x2)max=x1;elsemax=x2;if(max<x3)max=x3;
return(max);
}
編寫函數,求三個整型參數的最大值。
程序舉例2/*定義函數的返回值類型,函數名,形參*//*通過比較得到三個數的最大值放到max中*//*返回運算結果*/intmax(intx1,intx2,intx3)編75函數的返回值功能將被調函數中的結果值返回給主調函數。語句return(返回值表達式)或return表達式;或return;舉例intadd(intx,inty){intz;z=x+y;return(z);}函數的返回值功能將被調函數中的結果值返回給主調函數。語句re76
(1)函數的返回值是通過函數中的return語句獲得的。return語句將被調用函數中的一個確定值帶回主調函數中去。如果需要從被調用函數帶回一個函數值(供主調函數使用),被調用函數中必須包含return語句。如果不需要從被調用函數帶回函數值,可以不要return語句。一個函數中可以有一個以上的return語句,執行到哪一個return語句,哪一個語句起作用。return語句后面的括弧也可以不要,如returnz;它與“return(z);”等價。說明:說明:77例如,max(intx,inty){intz;z=x>y?x∶y;return(z);}
函數max可以改寫如下:max(intx,inty){return(x>y?x∶y);}(2)return后面的值可以是一個表達式這樣的函數體更為簡短,只用一個return語句就把求值和返回都解決了。例如,函數max可以改寫如下:(2)return后面的值可78(3)函數值的類型。既然函數有返回值,這個值當然應屬于某一個確定的類型,應當在定義函數時指定函數值的類型。C語言規定,凡不加類型說明的函數,一律自動按整型處理。
在定義函數時對函數值說明的類型一般應該和return語句中的表達式類型一致。例如,例2中用隱含方式指定max函數值為整型,而變量z也被指定為整型,通過return語句把z的值作為max的函數值,由max帶回主調函數。z的類型與max函數的類型是一致的,是正確的。(4)若無return語句,遇到函數結束的“}”時,自動返回調用函數(3)函數值的類型。既然函數有返回值,這個值當然應屬于某一79
(5)如果函數值的類型和return語句中表達式的值不一致,則以函數類型為準。對數值型數據,可以自動進行類型轉換。即函數類型決定返回值的類型。main(){floata,b;intc;scanf(“%f,%f,”&a,&b); max(floatx,floaty);c=max(a,b);printf("Maxis%d\n",c);}max(floatx,floaty){floatz;/*z為實型變量*/z=x>y?x∶y;return(z);}運行情況如下:1.5,2.5Maxis2(5)如果函數值的類型和return語句80printstar(){printf("**********");}main(){inta;a=printstar();printf("%d",a);}(6)無返回值的函數返回后帶回不確定值輸出:10voidprintstar(){printf("**********");}main(){inta;
a=printstar();printf("%d",a);}編譯錯誤!printstar()(6)無返回值的函數返回后帶回不確定81程序舉例2下面add函數的功能是求兩個參數的和,并將和值返回調用函數。函數中的錯誤是:voidadd(floata,floatb) {floatc;c=a+b;returnc;}voidadd(floata,floatb)floatadd(floata,floatb)程序舉例2下面add函數的功能是求兩個參數的和,并將827.3函數的調用函數調用的一般形式為
函數名(實參表列);
如果是調用無參函數,則“實參表列”可以沒有,但括弧不能省略。如果實參表列包含多個實參,則各參數間用逗號隔開。實參與形參的個數應相等,類型應一致。實參與形參按順序對應,一一傳遞數據。7.3函數的調用函數調用的一般形式為83函數調用方式調用方式函數調用語句函數表達式函數參數print_star(n);voidprint_star(intn){inti;for(i=1;i<=n;i++)printf("*");}x=max(a,b)+5;x=max(max(a,b),c);函數調用方式調用方式函數調用語句函數表達式函數參數prin84
1.函數語句把函數調用作為一個語句。如hello();這時不要求函數帶回值,只要求函數完成一定的操作。2.函數表達式函數出現在一個表達式中,這種表達式稱為函數表達式。這時要求函數帶回一個確定的值以參加表達式的運算。例如:c=2*max(a,b);函數max是表達式的一部分,它的值乘2再賦給c。3.函數參數函數調用作為一個函數的實參。例如:m=max(a,max(b,c));其中max(b,c)是一次函數調用,它的值作為max另一次調用的實參。m的值是a、b、c三者最大的。又如:printf(“%d”,max(a,b));也是把max(a,b)作為printf函數的一個參數。1.函數語句85調用函數的過程是:①為函數的所有形參分配內存單元。②計算各個實參表達式的值,一一對應的賦值給相應形參(若是無參函數,上述過程不執行)。③進入函數體,執行函數中的語句,實現函數的功能。④執行到return語句時,計算return語句中表達式的值(若是無返回值函數,本項不做),返回到主調函數。⑤釋放形參及本函數內的局部變量所占內存,繼續執行主調函數中的后繼語句。調用函數的過程是:86形式參數和實際參數在調用函數時,大多數情況下,主調函數和被調用函數之間有數據傳遞關系。這就是前面提到的有參函數。前面已提到:在定義函數時函數名后面括弧中的變量名稱為“形式參數”(簡稱“形參”),在主調函數中調用一個函數時,函數名后面括弧中的參數(可以是一個表達式)稱為“實際參數”(簡稱“實參”)。形式參數和實際參數在調用函數時,大多數情87參數傳遞主調函數向被調函數傳值的方式:賦值調用
把實參的值賦給形參。賦地址調用
把實參的地址付給形參。在被調函數中,用該地址訪問主調函數中的實參。實參形參調用返回單向值傳遞參數傳遞主調函數向被調函數傳值的方式:賦值調用實參形參調用返88C語言中,函數調用是值傳遞方式,即函數的實際參數和形式參數之間的數據傳遞方向是單向的,只能由實際參數傳遞給形式參數,而不能由形式參數傳遞給實際參數,是實際參數向形式參數單向賦值的關系。在內存中,形式參數與實際參數占用不同的內存單元。當調用函數時,給形式參數分配內存單元,將實際參數的值賦值給形式參數,調用后,形式參數單元釋放,實際參數仍保留調用前的值,形式參數值的變化不影響實際參數。函數參數及其傳遞方式C語言中,函數調用是值傳遞方式,即函數的實際參數和形式參數之89調用結束:35a:b:例5.6交換兩個數#include<stdio.h>main(){inta=3,b=5;printf(“a=%d,\tb=%d\n",a,b);printf("swapped:\n");
swap(a,b);printf(“a=%d,\tb=%d\n",a,b);}swap(intx,inty){inttemp;temp=x;x=y;y=temp;}35a:b:調用前:調用35x:y:35a:b:swap:temp35a:b:x:35y:353temp=xx=yy=temp調用結束:35a:b:例5.6交換兩個數35a:b:90程序舉例分析一下程序,寫出運行結果。#include<stdio.h>main(){inta=5,b=10;printf("a=%d,b=%d\n",a,b);fun(a,b); /*函數調用*/printf("a=%d,b=%d\n",a,b);}intfun(intx,inty)/*現代風格函數定義*/{x=3;y=3;return;}a=5,b=10a=5,b=10程序舉例分析一下程序,寫出運行結果。#include<s91
main(){inta,b,c;scanf("%d,%d",&a,&b);c=max(a,b);printf(“Maxis%d",c);}max(intx,inty)/*定義有參函數max*/{intz;z=x>y?x∶y;return(z);}運行情況如下:7,8Maxis8形參實參c=max(a,b);(main函數)(max函數)max(intx,inty){intz;z=x>y?x:y;return(z);}程序舉例形參實參c=max(a,b);(main函數)(max函92說明:實參必須有確定的值形參必須指定類型形參與實參類型一致,個數相同若形參與實參類型不一致,自動按形參類型轉換———函數調用轉換形參在函數被調用前不占內存;函數調用時為形參分配內存;調用結束,內存釋放說明:93例計算x的立方#include<stdio.h>floatcube(floatx){return(x*x*x);}main(){floata,product;printf("Pleaseinputvalueofa:");scanf("%f",&a);product=cube(a);printf(”Cubeof%.4fis%.4f\n",a,product);}xaproduct××××1.21.21.728程序舉例例計算x的立方#include<stdio.h>xap94在一個函數中調用另一函數(即被調用函數)需要具備哪些條件呢?(1)首先被調用的函數必須是已經存在的函數(是庫函數或用戶自己定義的函數)。(2)如果使用庫函數,一般還應該在本文件開頭用#include命令將調用有關庫函數時所需用到的信息“包含”到本文件中來。例如,#include<stdio.h>其中“stdio.h”是一個“頭文件”。在stdio.h文件中放了輸入輸出庫函數所用到的一些宏定義信息。如果不包含“stdio.h”文件中的信息,就無法使用輸入輸出庫中的函數。在一個函數中調用另一函數(即被調用函數)95(3)如果使用用戶自己定義的函數,而且該函數與調用它的函數(即主調函數)在同
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 有關特許經營合同(17篇)
- 七年級英語下冊 Unit 8 Is there a post office near here Section A 第2課時(3a-3c)教學設計 (新版)人教新目標版
- 豬場租賃合同集錦(16篇)
- 售后部個人工作計劃怎么寫(4篇)
- 安全教育幼兒園班會課總結(14篇)
- 借助校園資源整合科學與綜合實踐活動
- 人教版 (新課標)七年級上冊第一節 人口與人種教案及反思
- 管理培訓心得體會范文(16篇)
- 2025年初中學生愛國演講稿(5篇)
- 采購部日常總結匯報2025年(7篇)
- 2025年武漢數學四調試題及答案
- 中國紡織文化智慧樹知到期末考試答案2024年
- 2009年安徽省中考化學試卷【含答案可編輯】
- 越南工業到2025年發展戰略及到2035發展展望(提到鋼鐵)
- 電梯曳引機減速箱的設計、建模與運動仿真分析機械
- 河北省用人單位錄用人員身份核查登記表
- 《給教師的100條建議》電子書
- 老視的機制及治療的研究進展
- VDA6.3的P2-7條款
- 工程聯系單表格(模板)
- 混凝土攪拌機設計論文
評論
0/150
提交評論