亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 第13章 函數(二).htm

?? 用非常通俗的語言介紹了C++和C
?? HTM
?? 第 1 頁 / 共 5 頁
字號:
      <P>1)int max(int a, int b);</P>
      <P>2)float max(float a, int b);</P>
      <P>3)double max(double a, double b);</P>
      <P> </P>
      <P>現在我這樣調用:</P>
      <P>int larger = max(1, 2);</P>
      <P>被調用的將是第1)個函數。因為參數1,2是int類型。</P>
      <P> </P>
      <P>而:</P>
      <P>double larger = max(1.0, 2);</P>
      <P>被調用的將是第……注意了!是第3)個函數。為什么?</P>
      <P>首先它不能是第1)個,因為雖然參數2是int類型,但1.0卻不是int類型,如果匹配第1)函數,編譯器認為會有丟失精度之危險。</P>
      <P>然后,你可能忘了,一個帶小數的常數,例如1.0,在編譯器里,默認為比較保險的double類型(編譯器總是害怕丟失精度)。</P>
      <P> </P>
      <P>最后,關于這兩個規則,都是在同名的函數參數個數也相同的情況下需要考慮,如果參數個數不一樣:</P>
      <P>int max(int a, int b);</P>
      <P>int max(int a, int b ,int c);</P>
      <P>當然就沒有什么好限制了,編譯器不會傻到連兩個和三個都區分不出,除非……</P>
      <P> </P>
      <P><B>實現函數重載的附加規則:</B>有時候你必須附加考慮參數的默認值對函數重載的影響。</P>
      <P> </P>
      <P>比如:</P>
      <P>int max(int a, int b);</P>
      <P>int max(int a, int b ,int c = 0);</P>
      <P> </P>
      <P>此例中,函數重載將失敗,因為你在第二個max函數中設置了一個有默認值的參數,這將造成編譯器對下面的代碼到底調用了哪一個max感到迷惑。不要罵編譯器笨,你自已說吧,該調用哪個?</P>
      <P>int c = max(1, 2);</P>
      <P> </P>
      <P>沒法斷定。所以你應該理解、接受、牢記這條附加規則。</P>
      <P> </P>
      <P>事實上影響函數重載的還有其它規則,但我們學習這些就夠了。</P>
      <H4><A name=13.3.3>13.3.3</A> 參數默認值與函數重載的實例</H4>
      <P><B>例五:</B>參數默認值、函數重載的實例</P>
      <P> </P>
      <P>有關默認值和函數重載的例子,前面都已講得很多。這里的實例僅為了方便大家學習。請用CB打開下載的配套例子工程。所用的就是上面提到例子,希望大家自已動手分別寫一個默認值和重載的例子。</P>
      <P> </P>
      <H3><A name=13.4>13.4</A> inline 函數</H3>
      <P>從某種角度上講,inline對程序影響幾乎可以當成是一種編譯選項(事實上它也可以由編譯選項實現)。</P>
      <H4><A name=13.4.1>13.4.1</A> 什么叫inline函數?</H4>
      <P>inline(小心,不是online),翻譯成“內聯”或“內嵌”。意指:當編譯器發現某段代碼在調用一個內聯函數時,它不是去調用該函數,而是將該函數的代碼,整段插入到當前位置。</P>
      <P>這樣做的好處是省去了調用的過程,加快程序運行速度。(函數的調用過程,由于有前面所說的參數入棧等操作,所以總要多占用一些時間)。</P>
      <P>這樣做的不好處:由于每當代碼調用到內聯函數,就需要在調用處直接插入一段該函數的代碼,所以程序的體積將增大。</P>
      <P>拿生活現象比喻,就像電視壞了,通過電話找修理工來,你會嫌慢,于是干脆在家里養了一個修理工。這樣當然是快了,不過,修理工住在你家可就要占地兒了。</P>
      <P>(某勤奮好學之大款看到這段教程,沉思片刻,轉頭對床上的“二奶”說:</P>
      <P>“終于明白你和街上‘雞’的區別了”。</P>
      <P>“什么區別?”</P>
      <P>“你是內聯型。”)</P>
      <P> </P>
      <P>內聯函數并不是必須的,它只是為了提高速度而進行的一種修飾。要修飾一個函數為內聯型,使用如下格式:</P>
      <P> </P>
      <P>inline 函數的聲明或定義</P>
      <P> </P>
      <P>簡單一句話,在函數聲明或定義前加一個 inline 修飾符。</P>
      <P> </P>
      <P>inline int max(int a, int b)</P>
      <P>{</P>
      <P>&nbsp; return (a&gt;b)? a : b;</P>
      <P>}</P>
      <P> </P>
      <H4><A name=13.4.2>13.4.2</A> inline函數的規則</H4>
      <P>規則一、一個函數可以自已調用自已,稱為遞歸調用(后面講到),含有遞歸調用的函數不能設置為inline;</P>
      <P>規則二、使用了復雜流程控制語句:循環語句和switch語句,無法設置為inline;</P>
      <P>規則三、由于inline增加體積的特性,所以建議inline函數內的代碼應很短小。最好不超過5行。</P>
      <P>規則四、inline僅做為一種“請求”,特定的情況下,編譯器將不理會inline關鍵字,而強制讓函數成為普通函數。出現這種情況,編譯器會給出警告消息。</P>
      <P>規則五、在你調用一個內聯函數之前,這個函數一定要在之前有聲明或已定義為inline,如果在前面聲明為普通函數,而在調用代碼后面才定義為一個inline函數,程序可以通過編譯,但該函數沒有實現inline。</P>
      <P>比如下面代碼片段:</P>
      <P> </P>
      <P>//函數一開始沒有被聲明為inline:</P>
      <P>void foo();</P>
      <P> </P>
      <P>//然后就有代碼調用它:</P>
      <P>foo();</P>
      <P> </P>
      <P>//在調用后才有定義函數為inline:</P>
      <P>inline void foo()</P>
      <P>{</P>
      <P>&nbsp; ......</P>
      <P>}</P>
      <P> </P>
      <P>代碼是的foo()函數最終沒有實現inline;</P>
      <P> </P>
      <P>規則六、為了調試方便,在程序處于調試階段時,所有內聯函數都不被實現。</P>
      <P> </P>
      <P>最后是筆者的一點“建議”:如果你真的發覺你的程序跑得很慢了,99.9%的原因在于你不合理甚至是錯誤的設計,而和你用不用inline無關。所以,其實,inline根本不是本章的重點。</P>
      <P> </P>
      <P>所以,有關inline 還會帶來的一些其它困擾,我決定先不說了。</P>
      <P> </P>
      <H3><A name=13.5>13.5</A> 函數的遞歸調用(選修)</H3>
      <P>第4次從洗手間里走出來。在一周前擬寫有關函數的章節時,我就將遞歸調用的內容放到了最后。</P>
      <P> </P>
      <P>函數遞歸調用很重要,但它確實不適于初學者在剛剛接觸函數的時候學習。</P>
      <H4><A name=13.5.1>13.5.1</A> 遞歸和遞歸的危險</H4>
      <P>遞歸調用是解決某類特殊問題的好方法。但在現實生活中很難找到類似的比照。有一個廣為流傳的故事,倒是可以看出點“遞歸”的樣子。</P>
      <P>“從前有座山,山里有座廟,廟里有個老和尚,老和尚對小和尚說故事:從前有座山……”。</P>
      <P>在講述故事的過程中,又嵌套講述了故事本身。這是上面那個故事的好玩之處。</P>
      <P> </P>
      <P>一個函數可以直接或間接地調用自已,這就叫做“遞歸調用”。</P>
      <P>C,C++語言不允許在函數的內部定義一個子函數,即它無法從函數的結構上實現嵌套,而遞歸調用的實際上是一種嵌套調用的過程,所以C,C++并不是實現遞歸調用的最好語言。但只要我們合理運用,C,C++還是很容易實現遞歸調用這一語言特性。</P>
      <P> </P>
      <P>先看一個最直接的遞歸調用:</P>
      <P> </P>
      <P>有一函數F();</P>
      <P> </P>
      <P>void F()</P>
      <P>{</P>
      <P>&nbsp; F();</P>
      <P>}</P>
      <P> </P>
      <P>這個函數和“老和尚講故事”是否很象?在函數F()內,又調用了函數F()。</P>
      <P>這樣會造成什么結果?當然也和那個故事一樣,沒完沒了。所以上面的代碼是一段“必死”的程序。不信你把電腦上該存盤的存盤了,然后建個控制臺工程,填入那段代碼,在主函數main()里調用F()。看看結果會怎樣?WinNT,2k,XP可能好點,98,ME就不好說了……反正我不負責。出于“燃燒自己,照亮別人”的理念,我在自已的XP+CB6上試了一把,下面是先后出現的兩個報錯框:</P>
      <P> </P>
      <P><IMG height=117 src="第13章 函數(二).files/ls13.h23.gif" width=551 
      border=0></P>
      <P> </P>
      <P>這是CB6的調試器“偵察”到有重大錯誤將要發生,提前出來的一個警告。我點OK,然后無厭無悔地再按下一次F9,程序出現真正的報錯框:</P>
      <P> </P>
      <P><IMG height=114 src="第13章 函數(二).files/ls13.h15.gif" width=165 
      border=0></P>
      <P> </P>
      <P>這是程序拋出的一個異常,EStackOverflow這么看:E字母表示這是一個錯誤(Error),Stack正是我們前面講函數調用過程的“棧”,Overflow意為“溢出”。整個 
      StasckOverflow 意思就:棧溢出啦!</P>
      <P>“棧溢出”是什么意思你不懂?拿個杯子往里倒水,一直倒,直到杯子滿了還倒,水就會從杯子里溢出了。棧是用來往里“壓入”函數的參數或返回值的,當你無限次地,一層嵌套一層地調用函數時,棧內存空間就會不夠用,于是發生“棧溢出”。</P>
      <P>(必須解釋一下,本例中,void 
      F()函數既沒有返回值也沒有參數,為什么還會發生棧溢出?事實上,調用函數時,需要壓入棧中的,不僅僅是二者,還有某些寄存器的值,在術語稱為“現場保護”。正因為C,C++使用了在調用時將一些關鍵數值“壓入”棧,以后再“彈出”棧來實現函數調用,所以C,C++語言能夠實現遞歸。)</P>
      <P> </P>
      <P>這就是我們學習遞歸函數時,第一個要學會的知識:</P>
      <P> </P>
      <P><B>邏輯上無法自動停止的遞歸調用,將引起程序死循環,并且,很快造成棧溢出。</B></P>
      <P> </P>
      <P>怎樣才能讓程序在邏輯上實現遞歸的自動停止呢?這除了要使用到我們前面辛辛苦苦學習的流程控制語句以后,還要掌握遞歸調用所引起的流程變化。</P>
      <P> </P>
      <H4><A name=13.5.2>13.5.2</A> 遞歸調用背后隱藏的循環流程</H4>
      <P> </P>
      <P>遞歸引起什么流程變化?前面的黑體字已經給出答案:“循環”。自已調用自已,當然就是一個循環,并且如果不輔于我們前面所學的if...語句來控制什么時候可以繼續調用自身,什么時候必須結束,那么這個循環就一定是一個死循環。</P>
      <P>如圖:</P>
      <P> </P>
      <P><IMG height=188 src="第13章 函數(二).files/ls13.h18.gif" width=187 
      border=0></P>
      <P> </P>
      <P>遞歸調用還可間接形成:比如 A() 調用 B(); B() 又調用 A(); 雖然復雜點,但實質上仍是一個循環流程:</P>
      <P> </P>
      <P><IMG height=300 src="第13章 函數(二).files/ls13.h19.gif" width=220 
      border=0></P>
      <P> </P>
      <P>在這個循環之里,函數之間的調用都是系統實現,因此要想“打斷”這個循環,我們只有一處“要害”可以下手:在調用會引起遞歸的函數之前,做一個條件分支判斷,如果條件不成立,則不調用該函數。圖中以紅點表示。</P>
      <P> </P>
      <P>現在你明白了嗎?一個合理的遞歸函數,一定是一個邏輯上類似于這樣的函數定義:</P>
      <P> </P>
      <P>void F()</P>
      <P>{</P>
      <P>&nbsp; ……</P>
      <P>&nbsp; if(……)&nbsp; //先判斷某個條件是否成立</P>
      <P>&nbsp; {</P>
      <P>&nbsp;&nbsp;&nbsp;&nbsp; F(); //然后才調用自身</P>
      <P>&nbsp; }</P>
      <P> ……</P>
      <P>}</P>
      <P> </P>
      <P>在武俠小說里,知道了敵人的“要害”,就幾乎掌握了必勝的機會;然而,“遞歸調用”并不是我們的敵人。我們不是要“除掉”它,相反我們利用它。所以盡管我們知道了它的要害,事情還要解決。更重要的是要知道:什么時候該打斷它的循環?什么時候讓它繼續循環?</P>
      <P>這當然和具體要解決問題有關。所以這一項能力有賴于大家以后自已在解決問題不斷成長。就像我們前面的講的流程控制,就那么幾章,但大家今后卻要拿它們在程序里解決無數的問題。</P>
      <P>(有些同學開始合上課本準備下課)程序的各種流程最終目的是要合適地處理數據,而中間數據的變化又將影響流程的走向。在函數的遞歸調用過程中,最最重要的數據變化,就是參數。因此,大多數遞歸函數,最終依靠參數的變化來決定是否繼續。(另外一個依靠是改變函數外的變量)。</P>
      <P>所以我們必要徹底明了參數在遞歸調用的過程中如何變化。</P>
      <H4><A name=13.5.3>13.5.3</A> 參數在遞歸調用過程中的變化</H4>
      <P>我們將通過一個模擬過程來觀察參數的變化。</P>
      <P> </P>
      <P>這里是一個遞歸函數:</P>
      <P> </P>
      <P>void F(int a)</P>
      <P>{</P>
      <P>&nbsp; F(a+1);</P>
      <P>}</P>
      <P> </P>
      <P>和前面例子有些重要區別,函數F()帶了一個參數,并且,在函數體內調用自身時,我們<FONT 
      color=#ff0000>傳給它當前參數加1的值,作為新的參數</FONT>。</P>
      <P>紅色部分的話你不能簡單看過,要看懂。</P>
      <P> </P>
      <P>現在,假設我們在代碼中以1為初始參數,第一次調用F():</P>
      <P> </P>
      <P>F(1);</P>
      <P> </P>
      <P>現在,參數是1,依照我們前面“參數傳遞過程”的知識,我們知道1被“壓入”棧,如圖:</P>
      <P><IMG height=187 src="第13章 函數(二).files/ls13.h20.gif" width=271 
      border=0></P>
      <P>F()被第1次調用后,馬上它就調用了自身,但這時的參數是 
      a+1,a就是原參數值,為1,所以新參數值應為2。隨著F函數的第二次調用,新參數值也被入棧:</P>
      <P><IMG height=187 src="第13章 函數(二).files/ls13.h21.gif" width=322 
      border=0></P>
      <P>再往下模擬過程一致。第三次調用F()時,參數變成3,依然被壓入棧,然后是第四次……遞歸背后的循環在一次次地繼續,而參數a則在一遍遍的循環中不斷變化。</P>
      <P>由于本函數仍然沒有做結束遞歸調用的判斷,所以最后的最后:棧溢出。</P>
      <P> </P>
      <P>要對這個函數加入結束遞歸調用的邏輯判斷是非常容易的。

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日韩午夜精品电影| 日韩毛片高清在线播放| 日日摸夜夜添夜夜添精品视频| 欧美性生活影院| 亚洲一区二区在线免费看| 欧美色图一区二区三区| 天堂av在线一区| 亚洲精品一线二线三线无人区| 国产精品综合一区二区三区| 国产精品乱码人人做人人爱| 在线免费观看日本一区| 91原创在线视频| 久久久久9999亚洲精品| 经典三级在线一区| 欧美激情自拍偷拍| 99久久久久久| 偷拍与自拍一区| 奇米精品一区二区三区在线观看| 精品国产乱码久久久久久闺蜜| 国产福利精品导航| 一区二区三区日韩欧美| 欧美一卡二卡三卡| 成人亚洲一区二区一| 亚洲成人精品在线观看| 精品粉嫩aⅴ一区二区三区四区| 97成人超碰视| 国产又黄又大久久| 亚洲与欧洲av电影| 亚洲国产精品ⅴa在线观看| 欧美精品1区2区3区| 国产99精品国产| 热久久国产精品| 亚洲一二三四区| 色老综合老女人久久久| 久久91精品国产91久久小草| 亚洲欧洲日韩一区二区三区| 日韩欧美一区二区不卡| 91偷拍与自偷拍精品| 国产一区二区导航在线播放| 18成人在线观看| 欧美v亚洲v综合ⅴ国产v| 91成人国产精品| 国产成人在线免费| 奇米色一区二区三区四区| 亚洲女厕所小便bbb| 久久九九国产精品| 欧美一区二视频| 在线免费观看日韩欧美| 成人av动漫网站| 国产精品一区在线观看乱码| 麻豆成人av在线| 午夜一区二区三区视频| 亚洲日本在线a| 日本一区二区成人在线| 激情图区综合网| 青青草成人在线观看| 亚洲精品日产精品乱码不卡| 久久久精品国产免大香伊| 这里是久久伊人| 欧美色综合天天久久综合精品| 99在线精品视频| 国产成人欧美日韩在线电影| 国产在线播精品第三| 久久精品国产色蜜蜜麻豆| 婷婷久久综合九色综合绿巨人 | 国产麻豆日韩欧美久久| 日韩精品一二区| 日韩影视精彩在线| 日本美女一区二区| 奇米一区二区三区| 免费成人av资源网| 轻轻草成人在线| 美国十次综合导航| 激情文学综合插| 国产一区二区不卡| 麻豆久久一区二区| 一区二区欧美国产| 亚洲综合无码一区二区| 一区二区成人在线| 亚洲第一成人在线| 日韩电影一区二区三区四区| 婷婷亚洲久悠悠色悠在线播放| 日本在线不卡一区| 久久99热这里只有精品| 国产一区二区三区四区五区入口| 国产一区二区精品久久| 国产一区二区调教| 成人久久久精品乱码一区二区三区 | 2021中文字幕一区亚洲| 久久精品亚洲精品国产欧美kt∨| 中文欧美字幕免费| 亚洲码国产岛国毛片在线| 亚洲午夜一区二区| 奇米影视在线99精品| 国产美女精品一区二区三区| 国产ts人妖一区二区| 一本久久精品一区二区| 欧美日本韩国一区二区三区视频 | 最新中文字幕一区二区三区| 中文字幕中文在线不卡住| 亚洲天堂av一区| 亚洲成人自拍网| 国内不卡的二区三区中文字幕 | 91美女蜜桃在线| 欧美乱妇15p| 久久久久久久久岛国免费| 亚洲私人影院在线观看| 午夜精品在线视频一区| 国产麻豆一精品一av一免费 | 成人免费高清视频在线观看| 色婷婷精品大在线视频| 日韩免费高清av| 亚洲男人天堂av| 蜜臀av一区二区三区| av网站免费线看精品| 欧美一区二区三区人| 国产精品久久久久一区| 日日摸夜夜添夜夜添国产精品 | 91精品免费观看| 久久色在线视频| 亚洲综合色成人| 国产一区在线观看视频| 欧美在线免费播放| 久久久久久免费| 亚瑟在线精品视频| 99re这里只有精品首页| 精品国产一区二区三区四区四 | 国产精品成人在线观看| 日本不卡123| 99亚偷拍自图区亚洲| 日韩欧美一区二区免费| 一区二区三区国产精品| 丰满岳乱妇一区二区三区| 7777精品伊人久久久大香线蕉超级流畅 | 国产成人精品免费一区二区| 51精品国自产在线| 亚洲欧美另类小说视频| 91精品国产综合久久精品| 亚洲一区免费观看| 国产成人综合精品三级| 666欧美在线视频| 亚洲综合一二区| 99久久夜色精品国产网站| 欧美精品一区二区久久婷婷| 无码av免费一区二区三区试看| a级高清视频欧美日韩| 精品国产1区二区| 天堂成人免费av电影一区| 91浏览器入口在线观看| 国产日韩av一区二区| 国产精品一区二区在线观看网站| 欧美日本国产一区| 亚洲国产精品久久不卡毛片 | 粉嫩嫩av羞羞动漫久久久| 日韩美女一区二区三区四区| 亚洲va欧美va人人爽| 欧美中文字幕一区二区三区亚洲 | 成人美女在线观看| 国产精品 日产精品 欧美精品| 欧美精品xxxxbbbb| 午夜精品成人在线| 欧美日韩国产一级二级| 亚洲激情欧美激情| 91传媒视频在线播放| 一区二区三区自拍| 欧美性xxxxxxxx| 亚洲图片欧美一区| 欧美老年两性高潮| 午夜欧美2019年伦理| 91精品黄色片免费大全| 免费成人结看片| 精品1区2区在线观看| 国产成人精品免费看| 国产精品视频免费看| 99精品欧美一区二区蜜桃免费 | 精品国产欧美一区二区| 久久97超碰国产精品超碰| 久久久精品国产免大香伊| 成人午夜免费av| 亚洲精品一二三区| 精品视频全国免费看| 人人爽香蕉精品| 久久蜜桃av一区二区天堂| 成人黄色免费短视频| 亚洲欧美电影一区二区| 欧美女孩性生活视频| 裸体歌舞表演一区二区| 国产亚洲精品精华液| 国产成人亚洲综合色影视| 中文字幕中文字幕一区二区| 色婷婷久久久亚洲一区二区三区| 亚洲一级在线观看| 欧美一卡二卡在线| 国产精品1区2区| 一区二区三区免费在线观看| 日韩午夜激情免费电影| 成人一级片网址| 亚洲1区2区3区视频| 国产欧美久久久精品影院 | 欧美伊人久久大香线蕉综合69|