C程序設(shè)計(jì)語言揣錦華第2章函數(shù).ppt
《C程序設(shè)計(jì)語言揣錦華第2章函數(shù).ppt》由會(huì)員分享,可在線閱讀,更多相關(guān)《C程序設(shè)計(jì)語言揣錦華第2章函數(shù).ppt(97頁珍藏版)》請?jiān)谘b配圖網(wǎng)上搜索。
第2章函數(shù) 2 1函數(shù)的定義與使用2 2函數(shù)調(diào)用機(jī)制2 3遞歸函數(shù)2 4默認(rèn)參數(shù)的函數(shù)2 5內(nèi)聯(lián)函數(shù)2 6函數(shù)重載2 7函數(shù)模板2 8使用C 系統(tǒng)函數(shù) 2 1函數(shù)的定義與使用 在編輯一個(gè)大型程序時(shí) 即使各個(gè)函數(shù)的前后順序不同 程序執(zhí)行的開始點(diǎn)永遠(yuǎn)是主函數(shù) 主函數(shù)按照調(diào)用與被調(diào)用關(guān)系調(diào)用子函數(shù) 子函數(shù)如果與其它子函數(shù)又存在調(diào)用與被調(diào)用關(guān)系 當(dāng)然還可以再調(diào)用其它子函數(shù) 在一對調(diào)用與被調(diào)用關(guān)系中 我們把調(diào)用其它函數(shù)的函數(shù)稱為主調(diào)函數(shù) 被其它函數(shù)調(diào)用的函數(shù)稱為被調(diào)函數(shù) 在一個(gè)較為復(fù)雜的大型程序中 一個(gè)函數(shù)很可能同時(shí)扮演兩種不同的角色 主調(diào)函數(shù)與被調(diào)函數(shù) 即既調(diào)用別的函數(shù) 被調(diào)函數(shù) 又被另外的函數(shù) 主調(diào)函數(shù) 調(diào)用 函數(shù)一般應(yīng)遵守先定義后調(diào)用的原則 否則應(yīng)在調(diào)用函數(shù)中先進(jìn)行原形說明 2 1 1函數(shù)的定義一個(gè)完整的函數(shù)定義由兩部分組成 即函數(shù)頭與函數(shù)體 1 函數(shù)定義的一般語法形式 形式參數(shù)表 說明性語句序列 實(shí)現(xiàn)函數(shù)功能的語句系列 函數(shù)頭是指上述格式中的 形式參數(shù)表 其中函數(shù)名可由函數(shù)設(shè)計(jì)者命名 可以是任何一個(gè)不重復(fù)的合法的標(biāo)識符 唯一的例外是 主函數(shù)必須命名為main 函數(shù)體是指上述格式中被一對大括號括起的復(fù)合語句部分 該函數(shù)所應(yīng)實(shí)現(xiàn)的功能由相應(yīng)的復(fù)合語句完成 2 函數(shù)的類型和返回值函數(shù)頭部分的類型標(biāo)識符規(guī)定了函數(shù)的返回值類型 函數(shù)的返回值是返回給主調(diào)函數(shù)的處理結(jié)果 由函數(shù)體部分的return語句帶回 例如 returnvalue1 無返回值的函數(shù)其類型標(biāo)識符為void 不必有return語句 3 形式參數(shù)函數(shù)頭部分的形式參數(shù) 簡稱形參 表的內(nèi)容如下 類型l形參名1 類型2形參名2 類型n形參名n其中類型1 類型2 類型n是類型標(biāo)識符 表示形參的數(shù)據(jù)類型 int double float char bool等 形參名1 形參名2 形參名n是形參名 合法的自定義標(biāo)識符 形參是用來實(shí)現(xiàn)主調(diào)函數(shù)與被調(diào)函數(shù)之間的數(shù)據(jù)聯(lián)系 通常將函數(shù)所處理的數(shù)據(jù) 影響函數(shù)功能的因素或者函數(shù)處理的結(jié)果作為形參 對于無形參的函數(shù) 其形參表的內(nèi)容應(yīng)該為空 但代表函數(shù)的小括號對不能省略 函數(shù)在沒有被調(diào)用的時(shí)候其形參只是一個(gè)符號 它標(biāo)志著在形參出現(xiàn)的位置應(yīng)該有一個(gè)什么類型的數(shù)據(jù) 函數(shù)在被調(diào)用時(shí)才由主調(diào)函數(shù)將實(shí)際參數(shù) 簡稱實(shí)參 賦予形參 從這一點(diǎn)上說 C 中的函數(shù)與數(shù)學(xué)中的函數(shù)概念極其相似 例如 我們都熟悉的如下數(shù)學(xué)中的函數(shù)形式 f x 3x2 5x 2這個(gè)函數(shù)只有當(dāng)自變量x被賦以確定的值以后 才能計(jì)算出函數(shù)的值 2 1 2函數(shù)的調(diào)用如果沒有遵守先定義后調(diào)用的原則 調(diào)用函數(shù)之前先要在主調(diào)函數(shù)中聲明函數(shù)原型 在主調(diào)函數(shù)中 或所有函數(shù)之前 按如下形式進(jìn)行函數(shù)原型聲明 含類型說明的形參表 如果是在所有函數(shù)之前聲明了函數(shù)原型 那么該函數(shù)原型在本程序文件中任何地方都有效 也就是說 在本程序文件中任何地方都可以依照該原型調(diào)用相應(yīng)的函數(shù) 如果是在某個(gè)主調(diào)函數(shù)內(nèi)部聲明了被調(diào)函數(shù)原型 那么該原型就只能在這個(gè)函數(shù)內(nèi)部有效 聲明了函數(shù)原型之后 便可以按如下形式調(diào)用子函數(shù) 實(shí)參1 實(shí)參2 實(shí)參n 實(shí)參列表中應(yīng)給出與函數(shù)原型中形參個(gè)數(shù)相同 類型相符的實(shí)參 每個(gè)實(shí)參都可以是常量 變量或表達(dá)式三者之一 實(shí)參與實(shí)參之間用逗號作為分隔符 注意 這里的逗號不是順序求值運(yùn)算符 函數(shù)調(diào)用可以作為一條語句 這時(shí)函數(shù)可以沒有返回值 函數(shù)調(diào)用也可以出現(xiàn)在表達(dá)式中 這時(shí)就必須有一個(gè)明確的返回值 函數(shù)調(diào)用示例如下 例2 1 編寫一個(gè)函數(shù) 把華氏溫度轉(zhuǎn)換為攝氏溫度 公式為C F 32 5 9 公式中F代表華氏溫度 C代表攝氏溫度 在主函數(shù)中提示用戶輸入一個(gè)華氏溫度 并完成輸入及輸出 由函數(shù)完成轉(zhuǎn)化功能 程序代碼如下 includefloathstoss floatfHuashi 原型說明voidmain floatfHuashi cout fHuashi cout 華氏 fHuashi 度對應(yīng)攝氏溫度 hstoss fHuashi 度 endl 函數(shù)調(diào)用作為一個(gè)表達(dá)式出現(xiàn)在輸出語句中 floathstoss floatfHuashi floatfSheshi fSheshi fHuashi 32 5 9 return fSheshi 程序運(yùn)行結(jié)果為輸入一個(gè)華氏溫度值 68華氏68度對應(yīng)攝氏20度 例2 2 編寫一個(gè)求x的n次方的函數(shù) 分析 求x的n次方 實(shí)際是求x自乘n次的乘積 程序代碼如下 includedoublepower doubledDishu intiMi 原型說明voidmain cout 底數(shù)1 8的3次冪是 power 1 8 3 endl 函數(shù)調(diào)用作為一個(gè)表達(dá)式出現(xiàn)在輸出語句中 doublepower doubledDishu intiMi intiCount doubledResult 1 0 for iCount 1 iCount iMi iCount dResult dResult dDishu return dResult 程序運(yùn)行結(jié)果為底數(shù)1 8的3次冪是5 832 例2 3 輸入一個(gè)8位的二進(jìn)制數(shù) 將其轉(zhuǎn)換為十進(jìn)制數(shù)后再輸出 對于非法輸入 除0和1以外的任何字符 應(yīng)給出提示信息 分析 將二進(jìn)制數(shù)轉(zhuǎn)換為十進(jìn)制數(shù) 只要將二進(jìn)制數(shù)的每一位乘以該位的權(quán) 然后相加 例如 110100112 1 27 1 26 0 25 1 24 0 23 0 22 1 21 l 20 21110 所以 如果輸入00001101 則應(yīng)輸出13 可以直接引用例2 2中的函數(shù)power來求2的各次方 程序代碼如下 includedoublepower doubledDishu intiMi 函數(shù)原型說明voidmain intiCount 8 intiValue 0 charcChar boolbFlag true cout0 cin cChar if cChar 1 iCount if bFlag cout 十進(jìn)制值為 iValue endl doublepower doubledDishu intiMi intiCount doubledResult 1 0 for iCount 1 iCount iMi iCount dResult dResult dDishu return dResult 輸入符合要求時(shí) 僅有字符0和1 的程序運(yùn)行結(jié)果為輸入一個(gè)8位的二進(jìn)制數(shù) 11010011十進(jìn)制值 211輸入不符合要求時(shí) 含有除0和1以外的任何字符 的程序運(yùn)行結(jié)果為輸入一個(gè)8位的二進(jìn)制數(shù) 110lao11這不是一個(gè)二進(jìn)制數(shù) 不能正確轉(zhuǎn)換 例2 4 編寫一個(gè)函數(shù)可用來判斷任給的一個(gè)正整數(shù)是否為素?cái)?shù) 或質(zhì)數(shù) 再編寫主程序完成輸入 調(diào)用和輸出 素?cái)?shù)是指只能被1和它自身整除的數(shù) 分析 素?cái)?shù)的逆定義就是 一但某數(shù)n能被2 3 n 1中的任何一個(gè)數(shù)除盡 只要除法中有一次余數(shù)為零 則n肯定不是一個(gè)素?cái)?shù) 某數(shù)n若依次除以2 3 n 1 結(jié)果都除不盡 有余數(shù) 則n肯定是一個(gè)素?cái)?shù) 程序代碼如下 includeintiIsprime intiNum voidmain intiNum cout iNum if iIsprime iNum 1 cout iNum 是一個(gè)素?cái)?shù) endl elsecout iNum 不是一個(gè)素?cái)?shù) endl intiIsprime intiNum intiChushu boolbFlag false for iChushu 2 iChushu iNum 1 iChushu if iNum iChushu 0 bFlag true break if bFlag false return1 elsereturn0 第一次程序運(yùn)行結(jié)果為請輸入一個(gè)正整數(shù) 3131是一個(gè)素?cái)?shù)第二次程序運(yùn)行結(jié)果為請輸入一個(gè)正整數(shù) 119119不是一個(gè)素?cái)?shù) 2 1 3函數(shù)的參數(shù)傳遞函數(shù)的參數(shù)用于在調(diào)用函數(shù)與被調(diào)用函數(shù)之間進(jìn)行數(shù)據(jù)傳遞 在函數(shù)定義時(shí) 函數(shù)名后面括號內(nèi)的參數(shù)稱為形式參數(shù) 簡稱形參 在函數(shù)被調(diào)用時(shí) 函數(shù)名后面括號內(nèi)的參數(shù)稱為實(shí)際參數(shù) 簡稱實(shí)參 當(dāng)函數(shù)未被調(diào)用時(shí) C 編譯系統(tǒng)并沒有給函數(shù)的形參分配相應(yīng)的內(nèi)存空間 函數(shù)的形參更不會(huì)有實(shí)際的值 只有在函數(shù)被調(diào)用時(shí) C 編譯系統(tǒng)這時(shí)才為形參分配實(shí)際的存儲(chǔ)單元 并將實(shí)參與形參結(jié)合 實(shí)參可以是常量 變量或表達(dá)式 其類型必須與形參相符 函數(shù)的參數(shù)傳遞 指的就是形參與實(shí)參結(jié)合 簡稱形實(shí)結(jié)合 的過程 形實(shí)結(jié)合的方式有值調(diào)用和引用調(diào)用兩種 1 值調(diào)用值調(diào)用是指當(dāng)發(fā)生函數(shù)調(diào)用時(shí) 編譯系統(tǒng)為形參分配相應(yīng)的存儲(chǔ)空間并且直接將實(shí)參的值復(fù)制給形參 這樣形參和實(shí)參就各自擁有不同的存儲(chǔ)單元 且形參是實(shí)參的副本 因此 值調(diào)用過程是參數(shù)值的單向傳遞過程 一旦形參獲得了與實(shí)參相同的值就與實(shí)參脫離關(guān)系 以后不論形參發(fā)生多大的改變 都決不會(huì)反過來影響到實(shí)參 前面2 1 2節(jié)中的四道例題均屬于值調(diào)用方式 例2 5 從鍵盤輸入兩個(gè)整數(shù) 交換位置后輸出 交換未成功 includevoidswap inta intb voidmain intx y x 5 y 10 cout x x y y endl swap x y 交換x y的值 cout afterswap endl cout x x y y endl voidswap inta intb intt t a a b b t 程序運(yùn)行結(jié)果為x 5y 10afterswapx 5y 10分析 從上面的程序運(yùn)行結(jié)果可以看出 并沒有達(dá)到交換的目的 這是因?yàn)椴捎玫膫鬟f方式不合乎問題的要求 在單向值傳遞方式中 形參值雖確實(shí)進(jìn)行了交換 但這些改變對實(shí)參不起任何作用 執(zhí)行主調(diào)函數(shù)中的函數(shù)調(diào)用語句swap x y 后 編譯系統(tǒng)將實(shí)參x中的值5傳遞給虛參a 將實(shí)參y中的值10傳遞給虛參b 在swap函數(shù)中 a b中的值完成互換 返回主函數(shù)時(shí) 實(shí)參x y中的值不受虛參a b的影響 并未進(jìn)行交換 2 引用調(diào)用顯而易見 值調(diào)用時(shí)參數(shù)的傳遞方式是實(shí)參單向復(fù)制其值給虛參 如果我們想使子函數(shù)中對形參所做的任何更改也能及時(shí)反映給主函數(shù)中的實(shí)參 即希望形參與實(shí)參的影響是互相的或稱是雙向的 又該怎么辦呢 這就需要改變調(diào)用方式 即采用第二種參數(shù)傳遞方式 引用調(diào)用 引用是一種特殊類型的變量 可以被認(rèn)為是某一個(gè)變量的別名 通過引用名與通過被引用的變量名訪問變量的效果是一樣的 這就是說 對形參的任何操作也就直接作用于實(shí)參 例如 inta b int注意 聲明一個(gè)引用時(shí) 必須同時(shí)對它進(jìn)行初始化 使它與一個(gè)已存在的對象關(guān)聯(lián) 一旦一個(gè)引用被初始化后 就不能改變關(guān)聯(lián)對象 換言之 一個(gè)引用從它被聲明之后 就必須確定是哪個(gè)變量的別名 而且自始至終只能作為這一個(gè)變量的別名 不能另作他用 形參也可以引用的方式出現(xiàn)在形參表中 引用作為形參的情況與變量的引用稍有不同 這是因?yàn)?形參的初始化不在類型說明時(shí)進(jìn)行 而是在執(zhí)行主調(diào)函數(shù)中的調(diào)用語句時(shí) 才為形參分配內(nèi)存空間 同時(shí)用實(shí)參來初始化形參 例2 6 使用引用調(diào)用改寫例2 5的程序 使兩實(shí)參中的數(shù)真正進(jìn)行互換 includevoidswap int voidswap int 程序運(yùn)行結(jié)果為x 5y 10afterswapx 10y 5 分析 子函數(shù)swap的兩個(gè)參數(shù)都是引用 當(dāng)被調(diào)用時(shí) 它們分別被初始化成為a和b的別名 因此 在子函數(shù)swap中將兩個(gè)參數(shù)的值進(jìn)行交換后 交換結(jié)果可以返回主函數(shù)main 2 2函數(shù)調(diào)用機(jī)制 一個(gè)C 的源程序經(jīng)過編譯以后形成與源程序主名相同但后綴為 exe的可執(zhí)行文件 且存放在外存儲(chǔ)器中 當(dāng)該 exe的可執(zhí)行程序被運(yùn)行時(shí) 首先從外存將程序代碼裝載到內(nèi)存的代碼區(qū) 然后從main函數(shù)的起始處開始執(zhí)行 程序在執(zhí)行過程中 如果遇到了對其它函數(shù)的調(diào)用 則暫停當(dāng)前函數(shù)的執(zhí)行 保存下一條指令的地址 即返回地址 作為從子函數(shù)返回后繼續(xù)執(zhí)行的入口點(diǎn) 并保存現(xiàn)場 主要是一些寄存器的內(nèi)容 然后轉(zhuǎn)到子函數(shù)的入口地址 執(zhí)行子函數(shù) 當(dāng)遇到return語句或者子函數(shù)結(jié)束時(shí) 則恢復(fù)先前保存的現(xiàn)場 并從先前保存的返回地址開始繼續(xù)執(zhí)行 圖2 1說明了函數(shù)調(diào)用和返回的過程 圖中標(biāo)號標(biāo)明了執(zhí)行順序 圖2 1函數(shù)調(diào)用和返回的示意圖 例2 7 求設(shè)N 10 X 2 4 6 8 即求N事件中每次取2 4 6 8的組合數(shù) 分析 這個(gè)問題需要反復(fù)利用兩個(gè)公式 N N X N X 設(shè)計(jì)兩個(gè)函數(shù) 一個(gè)求整數(shù)階乘的函數(shù)lJiecheng和一個(gè)求組合數(shù)的函數(shù)lComb 由主函數(shù)main調(diào)用lComb lComb又調(diào)用lJiecheng 程序代碼如下 includelonglJiecheng intn longrt 1 inti for i 1 i n i rt rt i returnrt longlComb intN intX returnlJiecheng N lJiecheng X lJiecheng N X voidmain longlJiecheng intn longlComb intN intX intiNum x do cout iNum while iNum 10 for x 2 x 10 x 2 cout C iNum x lComb iNum x endl 程序運(yùn)行結(jié)果為請輸入事件數(shù) 大于等于8 11C 11 2 55C 11 4 330C 11 6 462C 11 8 165 2 3遞歸函數(shù) 遞歸函數(shù)又稱為自調(diào)用函數(shù) 其特點(diǎn)是 在函數(shù)內(nèi)部直接或間接地自己調(diào)用自己 所謂直接調(diào)用自身 就是指在一個(gè)函數(shù)的函數(shù)體中出現(xiàn)了對自身的調(diào)用語句 例如 voidfunc1 void func1 func1調(diào)用func1自身 所謂間接調(diào)用自身 就是一個(gè)函數(shù)func1調(diào)用另一個(gè)函數(shù)func2 而函數(shù)func2中又調(diào)用了函數(shù)func1 于是構(gòu)成間接遞歸 下面的例子屬于間接調(diào)用情況 voidfunc1 void func2 func1調(diào)用func2 voidfunc2 void func1 func2調(diào)用func1 func1函數(shù)就是通過func2實(shí)現(xiàn)間接遞歸 遞歸算法的實(shí)質(zhì)是將原有的問題分解為新的問題 而解決新問題時(shí)又用到了原有問題的解法 按照這一原則分解下去 每次出現(xiàn)的新問題都是原有問題的簡化的子集 而最終分解出來的問題 是一個(gè)已知解的問題 這便是有限的遞歸調(diào)用 例2 8 編寫函數(shù) 用遞歸的方法求n 的值 在主程序中實(shí)現(xiàn)任意輸入n值并輸出計(jì)算結(jié)果 分析 計(jì)算n 的公式如下 1 n 0 n n n 1 n 0 這是一個(gè)遞歸形式的公式 在描述階乘算法時(shí) 又用到了階乘 只不過求階乘的數(shù)在逐次減1 因而編程時(shí)也自然采用遞歸算法 遞歸的結(jié)束條件是n 0 程序代碼如下 includelongjc intn longrt if n 0 cout Dataerror endl elseif n 0 rt 1 遞歸的結(jié)束條件elsert n jc n 1 以參數(shù)減1的方式繼續(xù)遞歸returnrt voidmain longjc intn intn longresult do cout n while n 0 result jc n 首次調(diào)用處cout n result endl 程序運(yùn)行結(jié)果為輸入一個(gè)正整數(shù) 66 720 例2 9 有5個(gè)人坐在一起 問第1個(gè)人多少歲 他說比第2個(gè)人大2歲 問第2個(gè)人多少歲 他說比第3個(gè)人大2歲 問第3個(gè)人多少歲 他說比第4個(gè)人大2歲 問第4個(gè)人多少歲 他說比第5個(gè)人大2歲 最后問第5個(gè)人 他說是12歲 請問第1個(gè)人多少歲 分析 這是一個(gè)遞歸問題 每一個(gè)人的年齡都比其后那個(gè)人的年齡大2 即 age 1 age 2 2age 2 age 3 2age 3 age 4 2age 4 age 5 2age 5 12可以用公式表示如下 12 n 5 age n age n 1 2 n 5 程序代碼如下 includeintage intn intss if n 5 ss 12 elsess age n 1 2 return ss voidmain intage intn cout 第一個(gè)人的年齡為 age 1 歲 endl 程序運(yùn)行結(jié)果為第一個(gè)人的年齡為20歲 2 4默認(rèn)參數(shù)的函數(shù) 在函數(shù)定義中通過賦值運(yùn)算就可指定默認(rèn)參數(shù)值 一旦程序在調(diào)用該函數(shù)時(shí) 如果給出實(shí)參 則用實(shí)參初始化形參 如果沒有給出實(shí)參 則C 編譯系統(tǒng)自動(dòng)以預(yù)先賦值的默認(rèn)參數(shù)值作為傳入數(shù)值 一般情況下都將調(diào)用該函數(shù)時(shí)經(jīng)常用到的常數(shù)作為默認(rèn)參數(shù)值 這樣在調(diào)用時(shí)就無需每次都寫出該值了 指定默認(rèn)參數(shù)值可以使函數(shù)的使用更為簡單 同時(shí)也增強(qiáng)了函數(shù)的可重用性 例2 10 帶默認(rèn)形參值的函數(shù)例題 includeintmult intn intk 2 第二個(gè)形參具有默認(rèn)值 if k 2 return n n elsereturn mult n k 1 n voidmain cout endl mult 5 endl 形參n用實(shí)參來初始化為5 形參k采用默認(rèn)值2 實(shí)現(xiàn)5 5 cout mult 5 3 endl 用實(shí)參來初始化形參 n為5 k為3 實(shí)現(xiàn)5 5 5 程序運(yùn)行結(jié)果為25125 默認(rèn)形參值必須按從右向左的順序定義 在有默認(rèn)值的形參右面 不能出現(xiàn)無默認(rèn)值的形參 因?yàn)樵谡{(diào)用時(shí) 實(shí)參初始化形參是按從左向右的順序 例如 voidtry intj 3 intk 非法voidtry intj intk 2 intm 非法voidtry intj intk 7 合法voidtry intj intk 2 intm 3 合法voidtry intj 3 intk 2 intm 3 合法 默認(rèn)形參值應(yīng)該在函數(shù)原型中給出 例如 intmulti intx 2 inty 5 默認(rèn)形參值在函數(shù)原型中給出voidmain multi 并非無參調(diào)用 而是采用默認(rèn)值 x取值2 y取值5 intmulti intx inty return x y 在相同的作用域內(nèi) 默認(rèn)形參值的說明應(yīng)保持唯一 但如果在不同的作用域內(nèi) 允許說明不同的默認(rèn)形參 這里的作用域是指直接包含著函數(shù)原型說明的大括號所界定的范圍 對作用域概念的詳細(xì)介紹請參閱第5章 例如 intadd intx 2 inty 5 全局默認(rèn)形參值voidmain intadd intx 1 inty 9 局部默認(rèn)形參值 add 此處調(diào)用時(shí) 采用局部默認(rèn)形參值 x取值1 y取值9 voidfunc void add 此處調(diào)用時(shí) 采用全局默認(rèn)形參值 x取值2 y取值5 2 5內(nèi)聯(lián)函數(shù) 內(nèi)聯(lián)函數(shù) 也稱在線函數(shù) 是在C 中為提高程序運(yùn)行效率而引入的 所有函數(shù)調(diào)用時(shí)都會(huì)產(chǎn)生一些額外的開銷 主要是系統(tǒng)棧的保護(hù) 代碼的傳遞 系統(tǒng)棧的恢復(fù)以及參數(shù)傳遞等 對于一些函數(shù)體很小但又經(jīng)常使用的函數(shù) 由于被調(diào)用的頻率非常高 這種額外開銷也就很可觀 有時(shí)甚至?xí)\(yùn)行效率產(chǎn)生本質(zhì)的影響 使用內(nèi)聯(lián)函數(shù)正是解決這一問題的手段 內(nèi)聯(lián)函數(shù)不是在調(diào)用時(shí)發(fā)生轉(zhuǎn)移 而是在編譯時(shí)將函數(shù)體嵌入在每一個(gè)調(diào)用語句處 這樣就相對節(jié)省了參數(shù)傳遞 系統(tǒng)棧的保護(hù)與恢復(fù)等的開銷 內(nèi)聯(lián)函數(shù)在定義時(shí)使用關(guān)鍵字inline區(qū)別于一般函數(shù) 其語法形式如下 含類型說明的形參表 函數(shù)體 例如 inlineintmul inta intb returna b 當(dāng)程序中出現(xiàn)mul 2 3 4 的函數(shù)調(diào)用時(shí) 編譯程序就會(huì)將其擴(kuò)展為 2 3 4 關(guān)鍵字inline是一個(gè)編譯命令 編譯程序在遇到這個(gè)命令時(shí)將記錄下來 在處理內(nèi)聯(lián)函數(shù)的調(diào)用時(shí) 編譯程序就試圖產(chǎn)生擴(kuò)展碼 這樣從使用者的角度來看 內(nèi)聯(lián)函數(shù)在語法上與一般函數(shù)沒有什么區(qū)別 只是在編譯程序生成目標(biāo)代碼時(shí)才區(qū)別處理 注意 內(nèi)聯(lián)函數(shù)體內(nèi)一般不能有循環(huán)語句和switch語句 內(nèi)聯(lián)函數(shù)的定義必須出現(xiàn)在第一次被調(diào)用之前 對內(nèi)聯(lián)函數(shù)不能進(jìn)行異常接口聲明 如果違背了上述注意事項(xiàng)中的任一項(xiàng) 編譯程序就會(huì)無視關(guān)鍵字inline的存在 像處理一般函數(shù)一樣處理 不生成擴(kuò)展代碼 因此 只有很簡單而使用頻率很高的函數(shù)才被說明為內(nèi)聯(lián)函數(shù) 內(nèi)聯(lián)函數(shù)會(huì)擴(kuò)大目標(biāo)代碼 使用時(shí)要謹(jǐn)慎 例2 11 內(nèi)聯(lián)函數(shù)例題 include includeinlineintmax inta intb if a b returna elsereturnb voidmain inta b c d a 210 b 150 c 20 d max a b d max d c 編譯時(shí)兩個(gè)調(diào)用處均被替換為max函數(shù)體語句 cout Thebiggestof setw 5 a setw 5 b setw 5 c is d endl 程序運(yùn)行結(jié)果為Thebiggestof21015020is210 2 6函數(shù)重載 函數(shù)的重載也稱多態(tài)函數(shù) C 編譯系統(tǒng)允許為兩個(gè)或兩個(gè)以上的函數(shù)取相同的函數(shù)名 但是形參的個(gè)數(shù)或者形參的類型不應(yīng)相同 編譯系統(tǒng)會(huì)根據(jù)實(shí)參和形參的類型及個(gè)數(shù)的最佳匹配 自動(dòng)確定調(diào)用哪一個(gè)函數(shù) 這就是所謂的函數(shù)重載 對于沒有重載機(jī)制的C語言 每個(gè)函數(shù)必須有其不同于其它函數(shù)的名稱 即使操作是相同的 僅僅數(shù)據(jù)的類型不相同 也需要定義名稱完全不同的函數(shù) 這樣就顯得重復(fù)且效率低下 例如 定義求平方函數(shù) 就必須對整數(shù)的平方 浮點(diǎn)數(shù)的平方以及雙精度數(shù)的平方分別用不同的函數(shù)名 intisq intx inty floatfsq floatx floaty doubledsq doublex doubley 程序在調(diào)用這三個(gè)不同類型的函數(shù)時(shí) 是以名字加以區(qū)別的 需要記住并區(qū)別它們的名稱 顯然 這樣就造成了代碼的重復(fù) 使用起來也不方便 更不利于代碼的維護(hù) 對于具有重載機(jī)制的C 語言 允許功能相近的函數(shù)在相同的作用域內(nèi)以相同函數(shù)名定義 因而使函數(shù)方便使用 便于記憶 也使程序設(shè)計(jì)更加靈活 仍以上例而言 在C 中只要用一個(gè)函數(shù)名即可 如square 然后以賦給此函數(shù)的參數(shù)類型來決定是要計(jì)算int型 float型 還是double型的數(shù)的平方 上例在C 中的定義形式如下 intsquare intx floatsquare floatx doublesquare doublex 要計(jì)算square 3 時(shí) C 自動(dòng)使用第一種形式 計(jì)算square 3 25 時(shí) C 自動(dòng)使用第三種形式 計(jì)算square 3 25f 時(shí) C 自動(dòng)使用第二種形式 但是決不可以定義兩個(gè)具有相同名稱 相同參數(shù)類型和相同參數(shù)個(gè)數(shù) 只是函數(shù)返回值不同的重載函數(shù) 例如 以下定義是C 不允許的 intfunc intx floatfunc intx 由此可見 C 是按函數(shù)的參數(shù)表分辨相同名稱的函數(shù) 如果參數(shù)表相同 則認(rèn)為是錯(cuò)誤的說明 C 允許重載函數(shù)有數(shù)量不同的參數(shù)個(gè)數(shù) 當(dāng)函數(shù)名相同而參數(shù)個(gè)數(shù)不同時(shí) C 會(huì)自動(dòng)按參數(shù)個(gè)數(shù)定向到正確的要調(diào)用的函數(shù) 下例說明了C 的這一特性 例2 12 重載函數(shù)應(yīng)用例題 includeintadd intx inty intsum sum x y return sum intadd intx inty intz intsum sum x y z return sum voidmain inta b a add 5 10 b add 5 10 20 cout a a b b endl 程序運(yùn)行結(jié)果為a 15b 35 2 7函數(shù)模板 有很多時(shí)候 我們希望所設(shè)計(jì)的算法可以處理多種數(shù)據(jù)類型 但是 即使這一算法被設(shè)計(jì)為重載函數(shù) 也只是使用相同的函數(shù)名 函數(shù)體仍然要分別定義 如下面兩個(gè)求較小值的函數(shù) intsmall intx inty returnx y x y doublesmall doublex doubley returnx y x y 考察以上兩個(gè)函數(shù) 有如下特點(diǎn) 只有參數(shù)類型不同 返回值類型不同 功能則完全一樣 類似這樣的情況 可以使用函數(shù)模板 從而避免函數(shù)體的重復(fù)定義 函數(shù)模板可以用來創(chuàng)建一個(gè)通用功能的函數(shù) 以支持多種不同形參 簡化重載函數(shù)的函數(shù)體設(shè)計(jì) 它的最大特點(diǎn)是把函數(shù)所使用的數(shù)據(jù)類型作為參數(shù) 函數(shù)模板的定義形式如下 函數(shù)定義 例2 13 定義一個(gè)能交換兩個(gè)變量值的函數(shù) 要求用模板函數(shù)實(shí)現(xiàn) includetemplatevoidswap T voidmain intm 1 n 8 doubleu 5 5 v 99 3 cout m m n n endl cout u u v v endl swap m n 整型swap u v 雙精度型cout m與n u與v交換以后 endl cout m m n n endl cout u u v v endl 程序運(yùn)行結(jié)果為m 1n 8u 5 5v 99 3m與n u與v交換以后 m 8n 1u 99 3v 5 5分析 編譯系統(tǒng)從調(diào)用swap 時(shí) 根據(jù)實(shí)參的類型推導(dǎo)出函數(shù)模板的類型參數(shù) 于調(diào)用swap m n 由于實(shí)參m及n為int類型 所以 推導(dǎo)出模板中類型參數(shù)T為int 當(dāng)類型參數(shù)的含義確定后 編譯器將以函數(shù)模板為樣板生成一個(gè)函數(shù) intswap int x int y intz z y y x x z 同樣 對于調(diào)用swap u v 由于實(shí)參u v為double類型 所以 推導(dǎo)出模板中類型參數(shù)T為double 接著 編譯器將以函數(shù)模板為樣板 生成如下函數(shù) doubleswap double x double y doublez z y y x x z 因此 當(dāng)主函數(shù)第一次調(diào)用swap 時(shí) 執(zhí)行的實(shí)際上是由函數(shù)模板生成的函數(shù) intswap int x int y 當(dāng)主函數(shù)第二次調(diào)用swap 時(shí) 執(zhí)行的實(shí)際上是由函數(shù)模板生成的函數(shù) doubleswap double x double y 2 8使用C 系統(tǒng)函數(shù) C 不僅允許我們根據(jù)需要自定義函數(shù) 而且C 的系統(tǒng)庫中還提供了幾百個(gè)常用函數(shù)可供程序員使用 如求平方根函數(shù) sqrt 求浮點(diǎn)數(shù)或雙精度數(shù)的絕對值函數(shù) fabs 對數(shù)函數(shù) log 指數(shù)函數(shù) exp 三角函數(shù)等都屬于數(shù)學(xué)函數(shù) 輸入 輸出格式控制函數(shù)有setw setprecision 等 由前面已學(xué)習(xí)的知識可知 調(diào)用函數(shù)之前必須先聲明函數(shù)原型 系統(tǒng)函數(shù)的原型聲明已經(jīng)全部由系統(tǒng)提供了 并且已分類存在于不同的頭文件中 程序員需要做的事情 就是用include指令嵌入相應(yīng)的頭文件 然后便可以使用系統(tǒng)函數(shù)了 例如 要使用基本輸入 輸出流函數(shù)cin cout 函數(shù) 就必須嵌入頭文件iostream h 若要使用數(shù)學(xué)函數(shù) 如求絕對值函數(shù)abs fabs 三角函數(shù)sin cos tan 開平方函數(shù)sqrt 對數(shù)值函數(shù)log 以e為底的指數(shù)函數(shù)exp 就要嵌入頭文件math h 同樣 要使用輸入 輸出格式控制函數(shù)setw setprecision 就要嵌入頭文件iomanip h 例2 14 系統(tǒng)函數(shù)應(yīng)用例題 從鍵盤輸入一個(gè)角度值 求出該角度的正弦值 余弦值和正切值 分析 系統(tǒng)函數(shù)中提供了求正弦值 余弦值和正切值的函數(shù) sin cos 及tan 函數(shù)的說明在頭文件math h中 同樣 系統(tǒng)函數(shù)中也提供了輸入 輸出格式控制函數(shù) 如輸出域?qū)捒刂坪瘮?shù)setw 輸出精度控制函數(shù)setprecision 函數(shù)的說明在頭文件iomanip h中 因此 需要用到這些系統(tǒng)函數(shù)時(shí) 就必須將該函數(shù)所屬的頭文件以 include或 include 頭文件名 的形式寫在程序代碼開始部分 程序代碼如下 include include includeconstdoublepi 3 14159265 voidmain doublea b cin a b a pi 180 cout sin a setw 10 sin b endl cout cos a setw 10 cos b endl cout tan a setw 10 tan b endl 程序運(yùn)行結(jié)果為輸入 30sin 30 0 5cos 30 0 866025tan 30 0 57735 充分利用系統(tǒng)函數(shù) 可以大大減少編程的工作量 提高程序的運(yùn)行效率和可靠性 要使用系統(tǒng)函數(shù) 應(yīng)該注意以下兩點(diǎn) 了解所使用的C 開發(fā)環(huán)境提供了哪些系統(tǒng)函數(shù) 不同的編譯系統(tǒng)提供的系統(tǒng)函數(shù)有所不同 確定要使用的系統(tǒng)函數(shù)的聲明在哪個(gè)頭文件中 這也可以在庫函數(shù)參考手冊或聯(lián)機(jī)幫助中查到 例如 在MSDNLibraryVisualStudio6 0中查找VC 6 0系統(tǒng)函數(shù)的分類列表 首先在 活動(dòng)子集 欄選擇VisualC Documentation 然后按如下路徑選擇 VisualC Documentation UsingVisualC VisualC Programmer sGuide Run TimeLibraryReference Run TimeRoutinesbyCategory Run TimeRoutinesbyCategory 如圖2 2 該幫助系統(tǒng)中將函數(shù)按如下分類列出 獲取參數(shù) Argumentaccess 浮點(diǎn)支持 Floating pointsupport 緩沖區(qū)操作 Buffermanipulation 輸入與輸出 Inputandoutput 字節(jié)分類 Byteclassification 國際化 Internationalization 字符分類 Characterclassification 內(nèi)存分配 Memoryallocation 數(shù)據(jù)轉(zhuǎn)換 Dataconversion 處理機(jī)與環(huán)境控制 Processandenvironmentcontrol 調(diào)試 Debug 查找與排序 Searchingandsorting 目錄控制 Directorycontrol 字符串操作 Stringmanipulation 錯(cuò)誤處理 Errorhandling 系統(tǒng)調(diào)用 Systemcalls 異常處理 Exceptionhandling 時(shí)間管理 Timemanagement 文件處理 Filehandling 圖2 2MSDNLibraryVisualStudio6 0窗口- 1.請仔細(xì)閱讀文檔,確保文檔完整性,對于不預(yù)覽、不比對內(nèi)容而直接下載帶來的問題本站不予受理。
- 2.下載的文檔,不會(huì)出現(xiàn)我們的網(wǎng)址水印。
- 3、該文檔所得收入(下載+內(nèi)容+預(yù)覽)歸上傳者、原創(chuàng)作者;如果您是本文檔原作者,請點(diǎn)此認(rèn)領(lǐng)!既往收益都?xì)w您。
下載文檔到電腦,查找使用更方便
14.9 積分
下載 |
- 配套講稿:
如PPT文件的首頁顯示word圖標(biāo),表示該P(yáng)PT已包含配套word講稿。雙擊word圖標(biāo)可打開word文檔。
- 特殊限制:
部分文檔作品中含有的國旗、國徽等圖片,僅作為作品整體效果示例展示,禁止商用。設(shè)計(jì)者僅對作品中獨(dú)創(chuàng)性部分享有著作權(quán)。
- 關(guān) 鍵 詞:
- 程序設(shè)計(jì)語言 揣錦華第 函數(shù)
鏈接地址:http://www.820124.com/p-8616246.html