更深入的理解-函數(shù)進階

更深入的理解-函數(shù)進階

ID:42085907

大?。?31.51 KB

頁數(shù):25頁

時間:2019-09-07

更深入的理解-函數(shù)進階_第1頁
更深入的理解-函數(shù)進階_第2頁
更深入的理解-函數(shù)進階_第3頁
更深入的理解-函數(shù)進階_第4頁
更深入的理解-函數(shù)進階_第5頁
資源描述:

《更深入的理解-函數(shù)進階》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在教育資源-天天文庫

1、第18章更深入的理解——函數(shù)進階第10章中已經(jīng)討論了函數(shù)的基本知識,讓讀者對函數(shù)有了基本的認(rèn)識,本章從更深層次幫助讀者理解函數(shù)。從和函數(shù)關(guān)系最密切的調(diào)用和返回入手,函數(shù)的參數(shù)傳遞有傳值,傳指針2種方式,從類型的角度上看,參數(shù)不僅僅可以是系統(tǒng)內(nèi)建的數(shù)據(jù)類型,還可以是數(shù)組、結(jié)構(gòu)等。此外,遞歸編程機制,函數(shù)的作用域和可見域,變量的生存期、作用域和可見域等都是本章討論的重點。18.1參數(shù)傳遞的副本機制如果將函數(shù)比作劇本,那形參和實參的關(guān)系相當(dāng)于角色和演員的關(guān)系,函數(shù)的參數(shù)傳遞有傳值和傳地址兩種方式。傳值調(diào)用時,在函數(shù)內(nèi)對形參的改變都不會影響實參,要想在函數(shù)內(nèi)對實參進行操作,必須采用傳地址調(diào)用的方

2、式。這是形象化的理解,從本質(zhì)上說,這是由參數(shù)傳遞的副本機制決定的。所謂副本機制,是指copy(拷貝)的思想,不論是傳值調(diào)用還是傳址調(diào)用,編譯器都要為每個參數(shù)制作臨時副本,或稱拷貝,函數(shù)體中對參數(shù)的修改都是對副本的修改,下面具體分析之。18.1.1傳值調(diào)用的副本傳值調(diào)用的情況相對簡單,不論傳遞的參數(shù)如何,編譯器都為這些參數(shù)制作臨時副本,函數(shù)體中對參數(shù)的修改都是針對副本進行的,絲毫不會影響傳來的參數(shù),試通過下述一段示例,體會傳值調(diào)用的副本機制。18.1.2傳址調(diào)用的副本機制相比傳值調(diào)用,傳址調(diào)用似乎要復(fù)雜一點,但只要知道,傳址調(diào)用也是通過副本機制,便能很好地理解傳址調(diào)用的機理,同樣從一個形象

3、的例子入手。18.2函數(shù)返回值的副本機制如果要細分,函數(shù)返回也可以認(rèn)為存在傳值和傳址兩種方式。函數(shù)返回同樣也是根據(jù)副本機制來處理的,首先來回顧下函數(shù)返回的流程:當(dāng)執(zhí)行到return語句時,return的值被復(fù)制到某個內(nèi)存單元或寄存器中,其地址是由編譯器來維護的,程序員無法直接訪問該地址,也就是說,在函數(shù)執(zhí)行完畢,相關(guān)現(xiàn)場被撤銷前,返回的值被復(fù)制保存到了某個地方,編譯器訪問該位置即可知道函數(shù)的返回值。該位置即可看成是函數(shù)中返回值的副本。對函數(shù)返回取地址是不合法的,即假設(shè)存在如下函數(shù):intA(intb,intc);不允許使用如下形式的語句:&A(3,4);18.2.1return局部變量為

4、什么合法函數(shù)返回的副本機制很好地解釋了為什么return一個局部變量是合法的,來看一段簡單的求和函數(shù)代碼:intsum(inta,intb)/*函數(shù)定義*/{intc=a+b;/*局部變量c*/returnc;/*返回*/}……intd=sum(1,2);/*函數(shù)調(diào)用*/來看語句“intd=sum(1,2);”,該語句先執(zhí)行函數(shù)sum,sum函數(shù)執(zhí)行完畢后將結(jié)果賦值給int型變量d,如果從字面上理解,是將c賦值給d,但實際上,在執(zhí)行賦值操作時,由于函數(shù)sum已經(jīng)執(zhí)行完畢返回,函數(shù)中的局部變量c已被撤銷,不存在了。實際上,在c被撤銷前,函數(shù)已經(jīng)為返回值c創(chuàng)建了副本,保存在特定的位置上,賦值

5、操作是由該位置處的副本完成的,形象的示意如所示。18.2.2返回指針申請動態(tài)內(nèi)存下面來看一下如何通過返回指針在函數(shù)中動態(tài)申請內(nèi)存,試比較下述與的異同:代碼?通過返回指針傳遞動態(tài)內(nèi)存GetMemorySunccess218.2.3不要返回指向棧內(nèi)存的指針動態(tài)申請內(nèi)存是在堆中完成的,而函數(shù)返回不會釋放堆內(nèi)存,但不要忘記,函數(shù)返回時,棧內(nèi)存中的內(nèi)容會被自動清除,因此,不要返回指向棧內(nèi)存的指針。請讀者試著分析下述的問題所在:18.2.4返回指向只讀存儲區(qū)的指針如果將中的GetMemory函數(shù)修改如下,會怎樣?char*GetMemory(void)/*定義函數(shù)GetMemory*/{char*p

6、="Hello,C";/*棧內(nèi)存中開辟字符串*/returnp;/*返回局部指針*/}"Hello,C"作為常量字符串,位于程序的只讀存儲區(qū)(.rodata),此時,返回指向只讀存儲區(qū)的指針p并沒有問題,但該指針只能用于輸出,而不能用于輸入改寫。18.3函數(shù)與結(jié)構(gòu)體結(jié)構(gòu)體可以看成一種數(shù)據(jù)組織方式,將很多不同類型的相關(guān)數(shù)據(jù)打包,構(gòu)成一種新的類型,從這種意義上說,結(jié)構(gòu)體變量完全可以當(dāng)成是一種普通類型的變量來使用。結(jié)構(gòu)體變量作函數(shù)參數(shù)時,也有傳值和傳址兩種方式,函數(shù)返回亦是如此,既可以返回結(jié)構(gòu)體變量,也可以返回指向非局部結(jié)構(gòu)體變量的指針。18.3.1結(jié)構(gòu)體變量的傳值和傳址調(diào)用采用值傳遞時,在函

7、數(shù)內(nèi)將生成實參的“復(fù)制品”,如果參數(shù)多是像int,char之類的簡單變量,這些變量占用的內(nèi)存并不多,復(fù)制也快。但結(jié)構(gòu)或共用體變量往往由多個成員變量組成,占用內(nèi)存大,如果復(fù)制一份,會造成時間和空間雙重浪費。采用值傳遞不會造成時空浪費,因為不管是多么復(fù)雜的結(jié)構(gòu)類型,指針參數(shù)只占4個內(nèi)存字節(jié)。18.3.2結(jié)構(gòu)體變量的成員作為函數(shù)參數(shù)結(jié)構(gòu)體變量的數(shù)據(jù)成員作函數(shù)實參時,結(jié)構(gòu)體變量的數(shù)據(jù)成員可以當(dāng)成是普通變量來使用,同樣存在傳值和傳址兩種函數(shù)調(diào)

當(dāng)前文檔最多預(yù)覽五頁,下載文檔查看全文

此文檔下載收益歸作者所有

當(dāng)前文檔最多預(yù)覽五頁,下載文檔查看全文
溫馨提示:
1. 部分包含數(shù)學(xué)公式或PPT動畫的文件,查看預(yù)覽時可能會顯示錯亂或異常,文件下載后無此問題,請放心下載。
2. 本文檔由用戶上傳,版權(quán)歸屬用戶,天天文庫負責(zé)整理代發(fā)布。如果您對本文檔版權(quán)有爭議請及時聯(lián)系客服。
3. 下載前請仔細閱讀文檔內(nèi)容,確認(rèn)文檔內(nèi)容符合您的需求后進行下載,若出現(xiàn)內(nèi)容與標(biāo)題不符可向本站投訴處理。
4. 下載文檔時可能由于網(wǎng)絡(luò)波動等原因無法下載或下載錯誤,付費完成后未能成功下載的用戶請聯(lián)系客服處理。