深圳龍崗做網(wǎng)站的廈門網(wǎng)
函數(shù)的概述
函數(shù):實現(xiàn)一定功能的,獨立的代碼模塊。我們的函數(shù)一定是先定義,后使用。
使用函數(shù)的優(yōu)勢:
1. 我們可以通過函數(shù)提供功能給別人使用。當(dāng)然我們也可以使用別人提供的函數(shù),減少代碼量。
2. 借助函數(shù)可以減少重復(fù)性的代碼。
3. 實現(xiàn)結(jié)構(gòu)化(模塊化)
程序設(shè)計思想: 結(jié)構(gòu)化程序設(shè)計思想:將大型的任務(wù)功能劃分為相互獨立的小型的任務(wù)模塊來設(shè)計。
函數(shù)是C語言程序的基本組成單元:
C語言程序是由一個(必然是main函數(shù))或多個函數(shù)組成。
函數(shù)的分類
從函數(shù)實現(xiàn)的角度:
庫函數(shù):C語言標準庫實現(xiàn)并提供使用的函數(shù),比如常見的有printf(),scanf()
用戶自定義函數(shù):需要程序員自行實現(xiàn),開發(fā)中大部分都是這樣的函數(shù)
從函數(shù)形式的角度:
無參函數(shù):函數(shù)調(diào)用時,無需傳參,可配可不配返回值。
有參函數(shù):函數(shù)調(diào)用時,需要參數(shù)傳遞數(shù)據(jù),經(jīng)常需要配套返回值使用。
相關(guān)概念
主調(diào)函數(shù):主動去調(diào)用其他函數(shù)的函數(shù)。
被調(diào)函數(shù):被調(diào)用的函數(shù)
很多時候,一個函數(shù)既可以是主調(diào)函數(shù),也可以是被調(diào)函數(shù)。這種情況一般出自自定義函 數(shù)。
函數(shù)的定義
語法
函數(shù)首部:
返回類型:函數(shù)返回值的類型
函數(shù)名:函數(shù)的名稱,遵循標識符命名(使用英文字母、數(shù)字、_、$,不能以數(shù)字開頭,建議小寫 +下劃線命名法)
形參列表:用于接收主調(diào)函數(shù)傳遞的數(shù)據(jù),如果有多個用" , "分隔,且每一個形參都需要指定類 型。
面試題:
注意:
函數(shù)類型標識符變量類型說明符相同,它表示返回的函數(shù)值的類型。
在C語言中還可以定義無類型(即void類型)的函數(shù),這種函數(shù)不返回函數(shù)值,只是完成某種功 能。
如果省略函數(shù)的類型標識符,則默認為是int型。
函數(shù)中返回語句的形式為 return(表達式);或 return 表達式;其作用是將表達式的值作為函數(shù)值返 回給調(diào)用函數(shù)。其中表達式的類型應(yīng)與函數(shù)類型一致。
如果"形參表列"中有多個形式參數(shù),則它們之間要用" , "分隔。
如果形參表中有多個形參,即使它們的類型是相同的,在形參表中也只能逐個進行說明。 fun1(in t a,int b){}
一個完整C程序中的所有函數(shù)可以放在一個文件中,也可以放在 多個文件中。
案例
案例1:
案例2:
形參和實參
概念
形參(形式參數(shù)):
函數(shù)定義時指定的參數(shù),形參是用來接收數(shù)據(jù)的,函數(shù)定義時,系統(tǒng)不會為形參申請內(nèi)存,只有當(dāng)函 數(shù)調(diào)用時,系統(tǒng)才會為形參申請內(nèi)存,用于存儲實際參數(shù),并且當(dāng)函數(shù)返回,系統(tǒng)會自動回收為形參 申請的內(nèi)存資源。(本質(zhì)上所有函數(shù)都有return,只不過當(dāng)我們的函數(shù)返回類型是void的時候,return 關(guān)鍵字被省略了)
實參(實際參數(shù)):
函數(shù)調(diào)用時主調(diào)函數(shù)傳遞的數(shù)據(jù)參數(shù)(常量、變量、表達式..,只要有確定的值),實參是傳遞的 數(shù)據(jù)。
實參和形參必須類型相同。若不同時,按賦值規(guī)定自動進行類型轉(zhuǎn)換。
在C語言中,參數(shù)傳遞遵循 單向值傳遞 ,實參只是將自身的值傳遞給形參,而不是實參本身。形參 的值的改變不會影響實參。
實參與形參在內(nèi)存中占據(jù)不同的內(nèi)存空間,盡管可能實參和形參名稱是一樣的。
案例2:
函數(shù)的返回值
若不需要返回值,函數(shù)中可以沒有return語句。
一個函數(shù)中可以有多個return語句,但任一時刻只有一個return語句被執(zhí)行。
被調(diào)函數(shù)返回給主調(diào)函數(shù)的結(jié)果數(shù)據(jù)(可以是變量、常量、表達式,只要是有確定值即可。)
返回值類型一般情況下需要和函數(shù)中return語句返回的數(shù)據(jù)類型保持一致,如果不一致,以函數(shù)定 義時指定的返回類型為標準。也就是返回值類型和實際返回值可以存在自動類型轉(zhuǎn)換或者強制類型 轉(zhuǎn)換的關(guān)系。
案例1:
案例2:
案例3:
函數(shù)的調(diào)用
調(diào)用方式
1. 函數(shù)語句: test(); int result = max(2,4);
2. 函數(shù)表達式: 4 + max(2,4);
3. 函數(shù)參數(shù): printf("%d",max(2,4))
在一個函數(shù)中調(diào)用另一個函數(shù)須具備以下條件
① 被調(diào)用的函數(shù)必須是已經(jīng)定義的函數(shù);
② 若使用庫函數(shù),應(yīng)在本文件開頭用#include包含;
③ 若使用用戶定義的函數(shù),而用戶函數(shù)又在主調(diào)函數(shù)的后面,則應(yīng)在主調(diào)函數(shù)中對被調(diào)用的函數(shù)進 行聲明。聲明的作用是把函數(shù)名、函數(shù)參數(shù)的個數(shù)和類型等信息通知編譯系統(tǒng),以便在遇到函數(shù)時, 編譯系統(tǒng)能正確識別函數(shù),并檢查函數(shù)調(diào)用的合法性。
函數(shù)聲明
函數(shù)調(diào)用時,往往要遵循 先定義后調(diào)用 ,但如果我們對函數(shù)的調(diào)用操作出現(xiàn)在函數(shù)的定義之前,則需 要對函數(shù)進行聲明。
函數(shù)聲明的作用:
是把函數(shù)名、函數(shù)參數(shù)的個數(shù)和返回類型等信息通知給編譯系統(tǒng),以便于在遇到函數(shù)時,編譯系統(tǒng)能 正確識別函數(shù),并檢查函數(shù)調(diào)用的合法性。
聲明的方式:
函數(shù)首部后加上分號
?
函數(shù)首部后加上分號,可省略形參名,但不能省略參數(shù)類型。
函數(shù)的嵌套調(diào)用
函數(shù)不允許嵌套定義,但允許嵌套調(diào)用。
嵌套調(diào)用:在被調(diào)函數(shù)內(nèi)有去主動去調(diào)用其他函數(shù),這樣的函數(shù)調(diào)用方式,稱之為嵌套調(diào)用;
案例1:
案例2:
函數(shù)的遞歸調(diào)用
遞歸調(diào)用的含義:在一個函數(shù)中,直接或者間接調(diào)用了函數(shù)本身稱之為函數(shù)的遞歸調(diào)用。
遞歸調(diào)用的本質(zhì):
是一種循環(huán)結(jié)構(gòu),它不同于之前所學(xué)的while,do-while,for這樣的循環(huán)結(jié)構(gòu),這些循環(huán)結(jié)構(gòu)是借 助循環(huán)變量,而遞歸是利用函數(shù)自身實現(xiàn)循環(huán)結(jié)構(gòu),如果不加以控制,很容易產(chǎn)生死循環(huán)。
遞歸調(diào)用的注意事項:
1. 遞歸調(diào)用必須要有出口,一定要終止遞歸(否則會產(chǎn)生死循環(huán))。
2. 對終止條件的判斷一定要放在函數(shù)遞歸之前。
3. 進行函數(shù)的遞歸調(diào)用。
4. 函數(shù)遞歸的同時一定要將函數(shù)調(diào)用向出口逼近。
案例1
案例2:
數(shù)組做函數(shù)參數(shù)
注意:
當(dāng)用數(shù)組做函數(shù)的實際參數(shù)時,則形參應(yīng)該也要用數(shù)組/指針變量來接收,但請注意,此次并不 代表傳遞了數(shù)組中所有的元素數(shù)據(jù),而是傳遞了第一個元素的內(nèi)存地址(數(shù)組首地址),形參接收這 個地址后,則形參和實參就代表了同一塊內(nèi)存空間,則形參的數(shù)據(jù)修改會改變實參的。這種數(shù)據(jù)傳遞 方式我們可以稱之為“引用傳遞”。
如果用數(shù)組做函數(shù)形式參數(shù),那么我們提供另一個形參表示數(shù)組的元素個數(shù)。原因是數(shù)組形參代 表的僅僅是實際數(shù)組的首地址。也就是說形參只獲取到了實際數(shù)組元素的開始,并未獲取元素的結(jié) 束。所以提供另一個形參表示數(shù)組的元素個數(shù),可以防止在被調(diào)函數(shù)對實際數(shù)組元素訪問的越界。
但有一個例外,如果是用字符數(shù)組做形參,且實際數(shù)組中存放的是字符串?dāng)?shù)據(jù)(形參是字符數(shù) 組,實參是字符串)。則不用表示數(shù)組元素的個數(shù)的形參,原因是字符串本身會自動結(jié)束符\0。
案例-數(shù)組元素做函數(shù)實參:
案例2:
變量的作用域
引入問題
我們在函數(shù)設(shè)計過程中,經(jīng)常要考慮對參數(shù)的設(shè)計,換句話說,我們需要考慮函數(shù)需要幾個參數(shù),需 要什么類型的參數(shù),但我并沒有考慮函數(shù)是否需要提供參數(shù),如果說函數(shù)可以訪問到已定義的數(shù)據(jù), 則就不需要提供函數(shù)形參,那么我么到底要不要提供函數(shù)參數(shù),取決于什么?答案就是變量的作用域 (如果函數(shù)在變量的作用域范圍內(nèi),則函數(shù)可以直接訪問數(shù)據(jù))
變量的作用域
概念:變量的作用范圍,也就是說變量在什么范圍是有效的。
變量的分類
根據(jù)變量的作用域不同,變量可分為全局變量和局部變量
局部變量
全局變量
建議在全局變量定義時初始化。如果不初始化,系統(tǒng)會將全局變量初始化為0(0 | \0 |0.0)。
使用全局變量的優(yōu)缺點:
優(yōu)點:
1. 利用全局變量可以實現(xiàn)一個函數(shù)對外輸出的多個結(jié)果數(shù)據(jù)。
2. 利用全局變量可以減少函數(shù)形參個數(shù),從而降低內(nèi)存消耗,以及因形參傳遞帶來的時間消耗。
缺點:
1. 全局變量在程序的整個運行期間,始終占據(jù)內(nèi)存空間,會引起資源消耗。
2. 過多的全局變量會引起程序的混亂,造成程序結(jié)果錯誤。
3. 降低程序通用性,特別是當(dāng)我們進行函數(shù)移植時,不僅僅要移植函數(shù),還要考慮全局變量。
4. 違反了“高內(nèi)聚,低耦合”的程序設(shè)計原則。
總結(jié):我們發(fā)現(xiàn)弊大于利,建議盡量減少對全局變量的使用,函數(shù)之間要產(chǎn)生聯(lián)系,僅通過實參形參的方式產(chǎn)生聯(lián)系。
作用域舉例:
案例:
注意:
如果全局變量(外部變量)和局部變量同名,程序執(zhí)行的時候, 就近原則
變量的生命周期
概念:
變量在程序運行中的存在時間。 根據(jù)變量存在的時間不同,變量可分為靜態(tài)存儲方式和動態(tài)存儲方式。
變量的存儲類型
存儲類型
auto
auto存儲類型只能修飾局部變量,被auto修飾的局部變量是存儲在動態(tài)存儲區(qū)的。auto也是局部變 量默認的存儲類型。
static
修飾局部變量:局部變量會被存儲在靜態(tài)存儲區(qū)。局部變量的生命周期被延長,但是作用域不發(fā) 生改變。
修改全局變量:全局變量的生命周期不變,但作用域被衰減。一般限制全局變量只能在本文件 內(nèi)。
demo01.c
demo02.c
extern
外部存儲類型:只能修飾全局變量,次全局變量可以被其他文件訪問。相當(dāng)于擴展了全局變量的 作用域。
extern修飾外部變量,往往是外部變量進行聲明,聲明該變量是在外部文件中定義的;不是變量定 義。
demo01.c
demo02.c
register
寄存器存儲類型:只能修飾局部變量,用register修飾的局部變量會直接存儲到CPU的寄存器中, 往往將循環(huán)變量設(shè)
置為寄存器存儲類型。
面試題
static關(guān)鍵字的作用
1. static修飾局部變量,延長其生命周期,但不影響局部變量的作用域。
2. static修飾全局變量,不影響全局變量的生命周期,會限制全局變量的作用域僅限本文件內(nèi)使用;
3. static修飾函數(shù):此函數(shù)就稱為內(nèi)部函數(shù),僅限本文件內(nèi)調(diào)用。 static int funa(){..}
值傳遞與引用傳遞
值傳遞:發(fā)生在整型、浮點型、字符型,數(shù)據(jù)傳遞,傳遞的是數(shù)值,也就是內(nèi)存空間只能被當(dāng)前變 量獨享。
引用傳遞:發(fā)生在數(shù)組、指針、結(jié)構(gòu)體..,數(shù)據(jù)傳遞,傳遞的是地址值,也就是內(nèi)存空間可以被多 個變量共享。
內(nèi)部函數(shù)和外部函數(shù)
內(nèi)部函數(shù):使用static修飾的函數(shù),稱作內(nèi)部函數(shù),內(nèi)部函數(shù)只能在當(dāng)前文件中調(diào)用。
外部函數(shù):使用extern修飾的函數(shù),稱作外部函數(shù),extern是默認的,可以不寫,也就是說本質(zhì)上 我們所寫的函數(shù)都是外部函數(shù),建議外部函數(shù)在被其他文件調(diào)用的時候,在其他文件中聲明的時 候,加上extern關(guān)鍵字。
章節(jié)作業(yè)
編程題
1. 編寫一個函數(shù),通過輸入球的半徑,返回球的體積;
2. 編寫一個函數(shù),通過輸入一個數(shù)字字符,返回該數(shù)字
3. 編寫一個函數(shù),輸入四個數(shù)據(jù)分別表示2個點的x,y坐標,返回兩點之間的距離;
4. 編寫一個函數(shù),通過參數(shù)輸入一個整型數(shù),返回該數(shù)各位上數(shù)字的平方和;
5. 編寫一個函數(shù),通過參數(shù)輸入x的值,計算如下的數(shù)學(xué)函數(shù)值,當(dāng) x>5時, f(x) = 4x+7;否則 f(x) = -2x+3,返回結(jié)果值
6. 設(shè)計一個函數(shù),用來求出多個數(shù)據(jù)的平均值;
7. 設(shè)計一個函數(shù),用來查找一個字符串中某個字符的位置;
8. 設(shè)計一個函數(shù),把一個整型數(shù)字轉(zhuǎn)成對應(yīng)的字符串格式
9. 設(shè)計一個函數(shù),統(tǒng)計字符串中大寫字母的個數(shù)
10. 設(shè)計函數(shù),實現(xiàn)strcmp 的功能;
11. 編寫函數(shù),用于判斷輸入的字符是不是個數(shù)字。是返回1,不是返回0.
12. 設(shè)計一程序,實現(xiàn)一個簡單的計算器。 要求:有菜單函數(shù) 和加、減、乘、除的函數(shù) 主函數(shù)調(diào)用這些函數(shù)實現(xiàn)程序的功能.要求菜單函數(shù)能 夠輸出如下的界面
1、加法 2、減法 3、乘法 4、除法 0.退出
13. 設(shè)計函數(shù)實現(xiàn)冒泡排序;
思考題【選做】
14. 編寫一個函數(shù),將數(shù)組中的數(shù)據(jù)首尾互換