第3章 函數(shù)和程序結構
《第3章 函數(shù)和程序結構》由會員分享,可在線閱讀,更多相關《第3章 函數(shù)和程序結構(46頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、Chapter 3 函數(shù)和程序結構3.1 函數(shù)的組織3.2 局部變量和全局變量、命名空間std3.3 形參與實參3.4 引用和const3.5 缺省參數(shù)值3.6 函數(shù)重載3.7 內聯(lián)函數(shù)3.8 編譯預處理3.1 函數(shù)的組織函數(shù)的組織結構化程序設計方法結構化程序設計方法使用結構化程序設計方法解決復雜的問題:分解大問題小問題更小問題求解(調用)main()函數(shù)函數(shù)一個函數(shù)是根據(jù)進去的信息(輸入)和產生的東西(輸出結果)所定義的一個黑盒。函數(shù)用于把較大的計算任務分解成若干個較小的任務,使程序人員可以在其他函數(shù)的基礎上構造程序,而不需要從頭做起。一個設計得當?shù)暮瘮?shù)可以把具體操作細節(jié)對程序中不需要知道它
2、們的那些部分隱藏掉,從而使整個程序結構清楚,減輕了因修改程序所帶來的麻煩。程序示例程序示例計算計算(12+10)!/(12!+10!)for example:ch3/3-1-1.cpp for example:ch3/3-1-2.cpp2層結構,2個函數(shù),降低程序的構思、編寫、調試的復雜度,可讀性好函數(shù)定義返回類型 函數(shù)名(參數(shù)聲明列表)函數(shù)體;double max(double d1,double d2)return(d1d2?d1:d2);return語句用于從被調用函數(shù)向調用者返回值。沒有返回值的函數(shù)、沒有參數(shù)的函數(shù),用關鍵字void修飾。void f(void)cout “aaaa”d
3、2?d1:d2);Void main()double f1,f2;cin f1 f2;cout max(f1,f2);cout max(67.4,23);形參實參實際參數(shù)可以是一個常量,變量,或甚至可以是一個表達式。3.2 局部變量和全局變量局部變量和全局變量變量作用范圍(作用域)在函數(shù)內定義的變量(包括形參)局部變量 作用范圍:本函數(shù)內部 定義在復合語句內的變量 作用范圍:復合語句內部全局變量 在函數(shù)以外定義的變量,不從屬于任一函數(shù) 作用范圍:從定義處到源文件結束3-4.cpp變量作用范圍示例int x=1;void main()int a=2;.int b=3;.f();.int t=4;
4、void f()int x=5,b=6;.int a=7;x=?a=?b=?b=?x=?b=?t=?a=?x=1 a=2 b=3b沒定義 x=5 b=6 t=4 a沒定義 若局部變量與全局變量同名,局部變量優(yōu)先變量作用范圍示例int x=1;int f(int x)return(x+);main()int y;y=f(2);x=f(x);printf(“%d%d”,y,x);x=1變量作用范圍l如果局部變量與全局變量同名,局部變量優(yōu)先。l不要濫用全局變量有副作用int x=1;void f1()x+;void f2()x=5;void main()x=10;f1();cout x;f2();c
5、out x;11 5 程序是變量(全局)定義和函數(shù)定義的集合。函數(shù)之間的通信可以通過參數(shù)、函數(shù)返回值以及外部變量進行。函數(shù)可以以任意次序出現(xiàn)在源文件中。源程序可以分成多個文件,只要不把一個函數(shù)分在幾個文件中就行。關鍵字extern變量的定義與是聲明是有不同的意義。作用域運算符:命名空間std 3-5-1.cpp 3-5-2.cpp3.3 形參與實參形參與實參函數(shù)的參數(shù) 函數(shù)的參數(shù)分為形參和實參兩種。形參出現(xiàn)在函數(shù)定義中,在整個函數(shù)體內都可以使用,離開該函數(shù)則不能使用。實參出現(xiàn)在主調函數(shù)中,進入被調函數(shù)后,實參變量也不能使用。形參和實參的功能是作數(shù)據(jù)傳送。發(fā)生函數(shù)調用時,主調函數(shù)把實參的值傳送給
6、被調函數(shù)的形參從而實現(xiàn)主調函數(shù)向被調函數(shù)的數(shù)據(jù)傳送。函數(shù)的形參和實參具有以下特點:1.形參變量只有在被調用時才分配內存單元,在調用結束時,即刻釋放所分配的內存單元。因此,形參只有在函數(shù)內部有效。函數(shù)調用結束返回主調函數(shù)后則不能再使用該形參變量。2.實參可以是常量、變量、表達式、函數(shù)等,無論實參是何種類型的量,在進行函數(shù)調用時,它們都必須具有確定的值,以便把這些值傳送給形參。因此應預先用賦值,輸入等辦法使實參獲得確定值。3.實參和形參在數(shù)量上,類型上,順序上應嚴格一致,否則會發(fā)生“類型不匹配”的錯誤。值傳遞 函數(shù)調用中發(fā)生的數(shù)據(jù)傳送是單向的。即只能把實參的值傳送給形參,而不能把形參的值反向地傳送
7、給實參。因此在函數(shù)調用過程中,形參的值發(fā)生改變,而實參中的值不會變化。For example:ch3/3-6.cpp 如何實現(xiàn)函數(shù)調用中發(fā)生的數(shù)據(jù)傳送是雙向的。即修改了形參所指的單元,也就修改了實參。3.4 引用和引用和const引用就是給某一已存在的對象取一別名引用就是給某一已存在的對象取一別名(alias)(alias)。refcount is a reference of an intWhich int to reference exactly?is countas:int count=0;int&refcount=count;refcount=1;/here,count=1 count
8、+;/here,refcount=2;For example:ch3/3-8.cpprules when using references:1.A reference must be initialized when it is created.(Pointers can be initialized at any time.)2.int i;3.int&j;/4.j=i;5.2.Once a reference is initialized to an object,it cannot be changed to refer to another object.(Pointers can b
9、e pointed to another object at any time.)6.int i,k;7.int&j=i;8.int&j=k;/9.rules when using references:3.You cannot have NULL references.You must always be able to assume that a reference is connected to a legitimate piece of storage.int a=1;int&refint1=NULL;/References in functions int&fun(int&i)i+;
10、return i;用用constconst表示常量對象表示常量對象#define BUFSIZE 100 BUFSIZE只是一個名字,沒有存儲空間只是一個名字,沒有存儲空間問題:宏定義常量沒有類型信息;宏定義常量是問題:宏定義常量沒有類型信息;宏定義常量是全局的全局的(extern linkage);用宏定義常量編程,調用宏定義常量編程,調試時,不能直接知道它的名字。試時,不能直接知道它的名字。常量處理的老方法常量處理的老方法:C+C+中的常量處理方法中的常量處理方法:const:const的最初動機是的最初動機是取代預處理器取代預處理器definedefine進行值替代進行值替代For ex
11、ample:ch3/3-9.cppconst int bufsize=100;(1)有類型信息;有類型信息;const int i=20;chat chi;/正確正確 /以下程序錯:以下程序錯:int i;char chi;constconst用于函數(shù)參數(shù)和返回值用于函數(shù)參數(shù)和返回值intint f1(const f1(const intint&i)&i)i+;/Illegal-compile-time error,i+;/Illegal-compile-time error,Returning by const value例例1 1:const const intint g()g()retu
12、rn 1;return 1;例例2 2:const char*v()const char*v()return result of function v();return result of function v();3.5 缺省參數(shù)值缺省參數(shù)值在在C+C+中,函數(shù)聲明時,可以為一個或多個參中,函數(shù)聲明時,可以為一個或多個參數(shù)指定缺省參數(shù)值。數(shù)指定缺省參數(shù)值。例如:例如:/function definitionvoid delay(int k,int time)/function code body/function declarationvoid delay(int k,int time=30
13、0);/function calldelay(5);/等價與等價與delay(5,300);理解要點:理解要點:當函數(shù)調用執(zhí)行時,編譯器從左到右順序將實參與形參結合,當函數(shù)調用執(zhí)行時,編譯器從左到右順序將實參與形參結合,若未指定足夠的實參,則編譯器按同樣順序用函數(shù)聲明中的缺若未指定足夠的實參,則編譯器按同樣順序用函數(shù)聲明中的缺省值來補足所缺少的實參。省值來補足所缺少的實參。由于對缺省參數(shù)的處理是在函數(shù)調用表達式執(zhí)行時進行的,由于對缺省參數(shù)的處理是在函數(shù)調用表達式執(zhí)行時進行的,所以,在函數(shù)聲明中,所以,在函數(shù)聲明中,“=”后面可以是任意復雜的表達式,后面可以是任意復雜的表達式,甚至是函數(shù)調用。如
14、:甚至是函數(shù)調用。如:void delay(int k,int time=f(5);/其中其中f(5)是函數(shù)調用是函數(shù)調用所有帶缺省值的參數(shù)一律放在函數(shù)聲明中參數(shù)表的最右端。所有帶缺省值的參數(shù)一律放在函數(shù)聲明中參數(shù)表的最右端。void f(int,int y=1,int z);/因為:函數(shù)調用因為:函數(shù)調用f(2,4)將產生二義性:將產生二義性:4 y 還是還是 4 z void f(int,int y=1,int z=2);/在函數(shù)定義中,不再為參數(shù)指定缺省值。在函數(shù)定義中,不再為參數(shù)指定缺省值。(內聯(lián)函數(shù)除外內聯(lián)函數(shù)除外)3.6 函數(shù)重載函數(shù)重載一個函數(shù)名(標識符)可以被用作多個函數(shù)抽一個
15、函數(shù)名(標識符)可以被用作多個函數(shù)抽象的名字。編譯時,根據(jù)這些函數(shù)的參數(shù)個數(shù)、象的名字。編譯時,根據(jù)這些函數(shù)的參數(shù)個數(shù)、參數(shù)類型來區(qū)分(束定參數(shù)類型來區(qū)分(束定/綁定綁定binding)binding)For example:unit three:function_overloading.dsw二義性錯誤二義性錯誤Outline:要確保不同的參數(shù)類型確實不同。要確保不同的參數(shù)類型確實不同。例如:例如:typedef float real;float abs(float)/real abs(real)/函數(shù)的返回類型不能區(qū)分重載函數(shù)函數(shù)的返回類型不能區(qū)分重載函數(shù)例如:例如:int process
16、(int)/float process(int)/僅僅用了僅僅用了constconst而使參數(shù)類型有所不同,則而使參數(shù)類型有所不同,則不能區(qū)分。不能區(qū)分。例如例如:int process(int)/float process(const int)/Void Complex()apart=0.0;ipart=0.0;Void Complex(double d)apart=d;ipart=0.0;Void Complex(double a,double b)apart=a;ipart=b;Void Complex(double a=0.0,double b=0.0)apart=a;ipart=b;
17、When:Complex();/be equal to Complex(0.0,0.0)Complex(2);/Complex(2,0.0)3.7 內聯(lián)函數(shù)內聯(lián)函數(shù)function call need costs:involved from pushing arguments,making an assembly-language CALL,returning arguments,and performing an assembly-language RETURNFor example:ch3/3-10.cpp 在在C+C+中,用中,用inline functioninline functio
18、n來替換來替換帶參宏的使用。帶參宏的使用。C+C+的內聯(lián)機制和的內聯(lián)機制和C C中的帶中的帶參宏定義都是為了獲得較高的運行速度。參宏定義都是為了獲得較高的運行速度。使用宏和使用宏和內聯(lián)函數(shù)增加了代碼空間,但減內聯(lián)函數(shù)增加了代碼空間,但減少了程序執(zhí)行時間少了程序執(zhí)行時間。因為不再有函數(shù)調。因為不再有函數(shù)調用開銷。但用開銷。但C+C+的內聯(lián)機制比的內聯(lián)機制比C C中的帶參宏中的帶參宏定義更安全。定義更安全。#include inline float area(float r)return 3.14*r*r;int main()float f=2;float s=area(f+);coutfendl
19、sendl;return 0;inline function作用:在一個函數(shù)定義之前作用:在一個函數(shù)定義之前加上關鍵字加上關鍵字inline,則稱該則稱該函數(shù)為內聯(lián)函數(shù)。每當在其函數(shù)為內聯(lián)函數(shù)。每當在其它程序中有對該內聯(lián)函數(shù)的它程序中有對該內聯(lián)函數(shù)的調用,調用,C+編譯器都使用該編譯器都使用該內聯(lián)函數(shù)的代碼替換該內聯(lián)內聯(lián)函數(shù)的代碼替換該內聯(lián)函數(shù)的調用表達式。函數(shù)的調用表達式。使用內聯(lián)函數(shù)的優(yōu)點:使用內聯(lián)函數(shù)的優(yōu)點:參數(shù)的類型和函數(shù)返回值的類型都在函數(shù)聲明中進行明確的指定。參數(shù)的類型和函數(shù)返回值的類型都在函數(shù)聲明中進行明確的指定。這便于編譯器發(fā)現(xiàn)函數(shù)調用中的類型不一致的錯誤。這便于編譯器發(fā)現(xiàn)函數(shù)
20、調用中的類型不一致的錯誤。如果傳入函數(shù)的是表達式,則此表達式僅求值一次。如果傳入函數(shù)的是表達式,則此表達式僅求值一次。內聯(lián)函數(shù)只宜用于比較簡單的函數(shù)(不含循環(huán)語句和內聯(lián)函數(shù)只宜用于比較簡單的函數(shù)(不含循環(huán)語句和switch語句)。語句)。如果內聯(lián)函數(shù)的體很大,有可能使代碼的規(guī)模急劇增加。如果內聯(lián)函數(shù)的體很大,有可能使代碼的規(guī)模急劇增加。編譯器如何內聯(lián)編譯器如何內聯(lián)?64.內聯(lián)函數(shù)和編譯器內聯(lián)函數(shù)和編譯器 (1)編譯器如何實現(xiàn)內聯(lián)?編譯器如何實現(xiàn)內聯(lián)?(2)內聯(lián)的局限性內聯(lián)的局限性:a)假如函數(shù)太復雜假如函數(shù)太復雜,編譯器將不能執(zhí)行內聯(lián)編譯器將不能執(zhí)行內聯(lián)(復雜的函數(shù)定義順序、構造函數(shù)和復雜的函
21、數(shù)定義順序、構造函數(shù)和析構函數(shù)析構函數(shù)).b)假如在程序中假如在程序中,隱含或顯式取該函數(shù)的地址隱含或顯式取該函數(shù)的地址,則則 c)在程序的在程序的Debug版本版本,不執(zhí)行內聯(lián)不執(zhí)行內聯(lián) 3.8 編譯預處理編譯預處理 在前面各章中,已多次使用過以“#”號開頭的預處理命令。如包含命令#include,宏定義命令#define等。在源程序中這些命令都放在函數(shù)之外,而且一般都放在源文件的前面,它們稱為預處理部分。所謂預處理是指在進行編譯的第一遍掃描(詞法掃描和語法分析)之前所作的工作。預處理是語言的一個重要功能,它由預處理程序負責完成。當對一個源文件進行編譯時,系統(tǒng)將自動引用預處理程序對源程序中的
22、預處理部分作處理,處理完畢自動進入對源程序的編譯。語言提供了多種預處理功能,如宏定義、文件包含、條件編譯等。合理地使用預處理功能編寫的程序便于閱讀、修改、移植和調試,也有利于模塊化程序設計。本章介紹常用的幾種預處理功能。無參宏#define PI 3.14159#define NoBall 0#define PlayerBall 1#define ComputerBall 2/無參宏,用符號表示常量,For example:3-9.cpp有參宏和inline(內聯(lián))函數(shù)#define aera(x)PI*(x)*(x)利用有參宏來替代一些簡單的函數(shù)調用,為了減少由于調用函數(shù)所帶來的一些開銷.F
23、or example:3-10.cpp文件包含#include#include“chess.h 文件包含命令的功能是把指定的文件插入該命令行位置取代該命令行,從而把指定的文件和當前的源程序文件連成一個源文件。在程序設計中,文件包含是很有用的。一個大的程序可以分為多個模塊,由多個程序員分別編程。有些公用的符號常量或宏定義等可單獨組成一個文件,在其它文件的開頭用包含命令包含該文件即可使用。這樣,可避免在每個文件開頭都去書寫那些公用量,從而節(jié)省時間,并減少出錯。對文件包含命令還要說明以下幾點:1.使用尖括號表示在包含文件目錄中去查找(包含目錄是由用戶在設置環(huán)境時設置的),而不在源文件目錄去查找;使用雙引號則表示首先在當前的源文件目錄中查找,若未找到才到包含目錄中去查找。用戶編程時可根據(jù)自己文件所在的目錄來選擇某一種命令形式。2.一個include命令只能指定一個被包含文件,若有多個文件要包含,則需用多個include命令。3.文件包含允許嵌套,即在一個被包含的文件中又可以包含另一個文件。條件編譯 可以按不同的條件去編譯不同的程序部分,因而產生不同的目標代碼文件。這對于程序的移植和調試是很有用的。條件編譯有三種形式,下面分別介紹:1.第一種形式:#ifdef 標識符 程序段1#else 程序段2#endif Lab and ExerciseLab:實驗五
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。