面向對象程序設計(C++):第3章 函數_第1頁
面向對象程序設計(C++):第3章 函數_第2頁
面向對象程序設計(C++):第3章 函數_第3頁
面向對象程序設計(C++):第3章 函數_第4頁
面向對象程序設計(C++):第3章 函數_第5頁
已閱讀5頁,還剩67頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、第三章 函數目錄3.1 函數的定義與使用3.2 內聯函數3.3 帶缺省形參值的函數3.4 函數重載3.5 使用C+系統函數3.6 深度探索3.7 小結23.1.1 函數定義函數是面向對象程序設計中,對功能的抽象函數定義的語法形式類型標識符 函數名(形式參數表) 語句序列33.1 函數的定義與使用是被初始化的內部變量,壽命和可見性僅限于函數內部若無返回值,寫void3.1.1 函數定義(續)形式參數表 name1, name2, ., namen函數的返回值由 return 語句給出,例如:return 0無返回值的函數(void類型),不必寫return語句。43.1 函數的定義與使用3.1.

2、2 函數的調用調用前先聲明函數:若函數定義在調用點之前,則無需另外聲明;若函數定義在調用點之后,則需要在調用函數前按如下形式聲明函數原型: 類型標識符 被調用函數名(含類型說明的形參表);調用形式 函數名(實參列表) 嵌套調用函數可以嵌套調用,但不允許嵌套定義。遞歸調用函數直接或間接調用自身。53.1 函數的定義與使用例3-1編寫一個求x的n次方的函數#include using namespace std;/計算x的n次方double power(double x, int n) double val = 1.0;while (n-) val *= x;return val;int main

3、() cout 5 to the power 2 is power(5, 2) endl;return 0;63.1 函數的定義與使用 3.1.2 函數的調用例3-2 數制轉換題目: 輸入一個8位二進制數,將其轉換為十進制數輸出。例如:11012=1(23)+1(22)+0(21)+1(20)=1310 所以,如果輸入1101,則應輸出1373.1 函數的定義與使用 3.1.2 函數的調用#include using namespace std;double power (double x, int n); /計算x的n次方int main() int value = 0;cout = 0;

4、i-) char ch; cin ch; if (ch = 1) value += static_cast(power(2, i);cout Decimal value is value endl;return 0;double power (double x, int n) double val = 1.0;while (n-) val *= x;return val;83.1 函數的定義與使用 3.1.2 函數的調用運行結果:Enter an 8 bit binary number 01101001Decimal value is 105例3-2 (續)例3-3 編寫程序求的值的計算公式如

5、下:其中arctan用如下形式的級數計算:直到級數某項絕對值不大于10-15為止;和x均為double型。93.1 函數的定義與使用 3.1.2 函數的調用#include using namespace std;double arctan(double x) double sqr = x * x;double e = x;double r = 0;int i = 1;while (e / i 1e-15) double f = e / i;r = (i % 4 = 1) ? r + f : r - f;e = e * sqr;i += 2;return r;103.1 函數的定義與使用3.1

6、.2 函數的調用例3-3 (續)int main() double a = 16.0 * arctan(1 / 5.0); double b = 4.0 * arctan(1 / 239.0); /* 注意:因為整數相除結果取整,如果參數寫1/5,1/239,結果就都是0 */cout PI = a - b endl;return 0;113.1 函數的定義與使用 3.1.2 函數的調用運行結果:PI=3.14159例3-3 (續)例3-4尋找并輸出11999之間的數m,它滿足m、m2和m3均為回文數。回文:各位數字左右對稱的整數。例如:11滿足上述條件 112=121,113=1331。分析

7、:10取余的方法,從最低位開始,依次取出該數的各位數字。按反序重新構成新的數,比較與原數是否相等,若相等,則原數為回文。123.1 函數的定義與使用 3.1.2 函數的調用#include using namespace std;/判斷n是否為回文數bool symm(unsigned n) unsigned i = n;unsigned m = 0;while (i 0) m = m * 10 + i % 10; i /= 10; return m = n;133.1 函數的定義與使用 3.1.2 函數的調用例3-4(續)int main() for(unsigned m = 11; m 1

8、000; m+) if (symm(m) & symm(m * m) & symm(m * m * m) cout m = m; cout m * m = m * m; cout m * m * m = m * m * m endl; return 0;143.1 函數的定義與使用 3.1.2 函數的調用例3-4(續)例3-4(續)運行結果:m=11 m*m=121 m*m*m=1331m=101 m*m=10201 m*m*m=1030301m=111 m*m=12321 m*m*m=1367631153.1 函數的定義與使用 3.1.2 函數的調用例3-5計算如下公式,并輸出結果:其中r、

9、s的值由鍵盤輸入。sin x的近似值按如下公式計算,計算精度為10-6:163.1 函數的定義與使用 3.1.2 函數的調用#include #include /*對C+標準庫中數學函數的說明*/using namespace std;const double TINY_VALUE = 1e-10;double tsin(double x) double g = 0;double t = x;int n = 1;do g += t;n+;t = -t * x * x / (2 * n - 1) / (2 * n - 2); while (fabs(t) = TINY_VALUE); retur

10、n g;173.1 函數的定義與使用 3.1.2 函數的調用例3-5(續)int main() double k, r, s;cout r;cout s;if (r * r = s * s) k=sqrt(tsin(r)*tsin(r)+tsin(s)*tsin(s);else k = tsin(r * s) / 2;cout k endl;return 0;183.1 函數的定義與使用 3.1.2 函數的調用運行結果:r=5s=81.37781例3-5 (續)例3-6 投骰子的隨機游戲每個骰子有六面,點數分別為1、2、3、4、5、6。游戲者在程序開始時輸入一個無符號整數,作為產生隨機數的種子

11、。每輪投兩次骰子,第一輪如果和數為7或11則為勝,游戲結束;和數為2、3或12則為負,游戲結束;和數為其它值則將此值作為自己的點數,繼續第二輪、第三輪.直到某輪的和數等于點數則取勝,若在此前出現和數為7則為負。由rolldice函數負責模擬投骰子、計算和數并輸出和數。193.1 函數的定義與使用 3.1.2 函數的調用例3.6 (續)rand函數原型:int rand(void);所需頭文件:功能和返回值:求出并返回一個偽隨機數srand函數原型:void srand(unsigned int seed);參數:seed產生隨機數的種子。所需頭文件:功能:為使rand()產生一序列偽隨機整數而

12、設置起始點。使用1作為seed參數,可以重新初化rand()。203.1 函數的定義與使用 3.1.2 函數的調用#include #include using namespace std;/投骰子、計算和數、輸出和數int rollDice() int die1 = 1 + rand() % 6;int die2 = 1 + rand() % 6;int sum = die1 + die2;cout player rolled die1 + die2 = sum endl;return sum;213.1 函數的定義與使用 3.1.2 函數的調用例3-6(續)enum GameStatus

13、WIN, LOSE, PLAYING ;int main() int sum, myPoint;GameStatus status;unsigned seed; cout seed;/輸入隨機數種子srand(seed);/將種子傳遞給rand()sum = rollDice(); /第一輪投骰子、計算和數223.1 函數的定義與使用 3.1.2 函數的調用例3-6(續)switch (sum) case 7: /如果和數為7或11則為勝,狀態為WINcase 11: status = WIN; break;case 2: /和數為2、3或12則為負,狀態為LOSEcase 3: case 1

14、2: status = LOSE; break;default: /*其它情況,游戲尚無結果,狀態為 PLAYING,記下點數,為下一輪做準備 */ status = PLAYING; myPoint = sum; cout point is myPoint endl; break;233.1 函數的定義與使用 3.1.2 函數的調用例3-6(續)while (status = PLAYING) /只要狀態仍為PLAYING,就繼續進 行下一輪 sum = rollDice(); if (sum = myPoint) /某輪的和數等于點數則取勝 status = WIN; else if (s

15、um = 7) /出現和數為7則為負 status = LOSE;/當狀態不為PLAYING時上面的循環結束,以下程序段輸出游戲結果if (status = WIN) cout player wins endl;else cout player loses endl;return 0; 243.1 函數的定義與使用 3.1.2 函數的調用例3-6(續)例3-6(續)運行結果:Please enter an unsigned integer:23player rolled 6 + 3 = 9point is 9player rolled 5 + 4 = 9player wins253.1 函數的

16、定義與使用 3.1.2 函數的調用嵌套調用263.1 函數的定義與使用 3.1.2 函數的調用main調fun1()結束fun1()調fun2()返回fun2()返回例3-7 輸入兩個整數,求平方和#include using namespace std;int fun2(int m) return m * m;int fun1(int x,int y) return fun2(x) + fun2(y);273.1 函數的定義與使用 3.1.2 函數的調用int main() int a, b;cout a b;cout The sum of square of a and b: fun1(a

17、, b) endl;return 0;283.1 函數的定義與使用 3.1.2 函數的調用運行結果:Please enter two integers(a and b): 3 4The sum of square of a and b: 25例3-7 (續)遞歸調用293.1 函數的定義與使用 3.1.2 函數的調用函數直接或間接地調用自身,稱為遞歸調用。遞歸過程的兩個階段:遞推: 4!=43!3!=32!2!=21!1!=10!0!=1未知 已知回歸:4!=43!=243!=32!=62!=21!=21!=10!=10!=1未知 已知例3-8 求n!分析:計算n!的公式如下:這是一個遞歸形式

18、的公式,應該用遞歸函數實現。303.1 函數的定義與使用 3.1.2 函數的調用#include using namespace std;unsigned fac(int n)unsigned f;if (n = 0) f = 1; else f = fac(n - 1) * n; return f;int main() unsigned n;cout n;unsigned y = fac(n);cout n ! = y endl;return 0;313.1 函數的定義與使用 3.1.2 函數的調用運行結果:Enter a positive integer:88! = 40320例3-8(續

19、)例3-9用遞歸法計算從n個人中選擇k個人組成一個委員會的不同組合數。分析: 由n個人里選k個人的組合數 = 由n-1個人里選k個人的組合數 +由n-1個人里選k-1個人的組合數當n = k或k = 0時,組合數為1323.1 函數的定義與使用 3.1.2 函數的調用#include using namespace std;int comm(int n, int k) if (k n) return 0;else if (n = k | k = 0) return 1;else return comm(n - 1, k) + comm(n - 1, k - 1);int main() int

20、n, k;cout n k;cout C(n, k) = comm(n, k) endl;return 0;333.1 函數的定義與使用 3.1.2 函數的調用運行結果:18 58568例3-9(續)例3-10有三根針A、B、C。A針上有N個盤子,大的在下,小的在上,要求把這N個盤子從A針移到C針,在移動過程中可以借助B針,每次只允許移動一個盤,且在移動過程中在三根針上都保持大盤在下,小盤在上。343.1 函數的定義與使用 3.1.2 函數的調用ABC例3-10(續)分析:將n 個盤子從A針移到C針可以分解為下面三個步驟:將A 上n-1個盤子移到 B針上(借助C針);把A針上剩下的一個盤子移到

21、C針上;將n-1個盤子從B針移到C針上(借助A針);事實上,上面三個步驟包含兩種操作:將多個盤子從一個針移到另一個針上,這是一個遞歸的過程。 hanoi函數實現。將1個盤子從一個針上移到另一針上。用move函數實現。353.1 函數的定義與使用 3.1.2 函數的調用#include using namespace std;/把src針的最上面一個盤子移動到dest針上void move(char src, char dest) cout src dest endl;/把n個盤子從src針移動到dest針,以medium針作為中介void hanoi(int n, char src, char

22、 medium, char dest) if (n = 1) move(src, dest);else hanoi(n - 1, src, dest, medium); move(src, dest); hanoi(n - 1, medium, src, dest);363.1 函數的定義與使用 3.1.2 函數的調用例3-10(續)int main() int m;cout m;cout the steps to moving m diskes: CA - BC - BA - CB - AB - CA - C例3-10(續)3.1 函數的定義與使用 3.1.2 函數的調用3.1.3 函數的參

23、數傳遞在函數被調用時才分配形參的存儲單元。實參可以是常量、變量或表達式。實參類型必須與形參相符。值傳遞是傳遞參數值,即單向傳遞。引用傳遞可以實現雙向傳遞常引用作參數可以保障實參數據的安全393.1 函數的定義與使用值傳遞舉例403.1 函數的定義與使用 3.1.3 函數的參數傳遞XN被調函數:主調函數:3 2.5AD = power(A,3) 2.53double power(double X,int N)例3-11 輸入兩個整數交換后輸出#includeusing namespace std;void swap(int a, int b) int t = a;a = b;b = t;int

24、main() int x = 5, y = 10;cout x = x y = y endl;swap(x, y);cout x = x y = y endl;return 0;413.1 函數的定義與使用 3.1.3 函數的參數傳遞運行結果:x = 5 y = 10 x = 5 y = 1042a=b;5 x10 y5 a10 b執行主函數中的函數調用swap(x,y);t=a;5 x10 y5 a10 b5tb=t;5 x10 y10 a5 b5t5 x10 y10 a10 b5t在swap子函數中返回主函數以后5x10y3.1 函數的定義與使用 3.1.3 函數的參數傳遞引用傳遞引用(&

25、)是標識符的別名,例如:int i, j;int &ri = i; /建立一個int型的引用ri,并將其 /初始化為變量i的一個別名j = 10;ri = j;/相當于 i = j;聲明一個引用時,必須同時對它進行初始化,使它指向一個已存在的對象。一旦一個引用被初始化后,就不能改為指向其它對象。引用可以作為形參void swap(int &a, int &b) .433.1 函數的定義與使用 3.1.3 函數的參數傳遞例3-12 輸入兩個整數交換后輸出#includeusing namespace std;void swap(int& a, int& b) int t = a;a = b;b

26、= t;int main() int x = 5, y = 10;cout x = x y = y endl;swap(x, y);cout x = x y = y endl;return 0;443.1 函數的定義與使用 3.1.3 函數的參數傳遞運行結果:x = 5 y = 10 x = 10 y = 545t=a;x5t5x 的引用axy510y 的引用x 的引用aby 的引用x 的引用abx10y10a=bb=t;y5t5y 的引用bxy105swap(x,y);3.1 函數的定義與使用 3.1.3 函數的參數傳遞例3-13值傳遞與引用傳遞的比較/3_13.cpp#include #i

27、nclude using namespace std;void fiddle(int in1, int &in2) in1 = in1 + 100;in2 = in2 + 100;coutThe values are ;cout setw(5) in1;cout setw(5) in2 endl;463.1 函數的定義與使用 3.1.3 函數的參數傳遞int main() int v1 = 7, v2 = 12; cout The values are ; cout setw(5) v1; cout setw(5) v2 endl; fiddle(v1, v2); cout The value

28、s are ; cout setw(5) v1; cout setw(5) v2 endl; return 0;3.2 內聯函數聲明時使用關鍵字 inline。編譯時在調用處用函數體進行替換,節省了參數傳遞、控制轉移等開銷。注意:內聯函數體內不能有循環語句和switch語句。內聯函數的聲明必須出現在內聯函數第一次被調用之前。對內聯函數不能進行異常接口聲明。47例3-14 內聯函數應用舉例#include using namespace std;const double PI = 3.14159265358979;inline double calArea(double radius) retu

29、rn PI * radius * radius;int main() double r = 3.0;double area= calArea(r);cout area endl;return 0;483.2 內聯函數3.3 帶缺省形參值的函數函數在聲明時可以預先給出缺省的形參值,調用時如給出實參,則采用實參值,否則采用預先給出的缺省形參值。例如:int add(int x = 5,int y = 6) return x + y;int main() add(10,20);/10+20add(10); /10+6add(); /5+649缺省形參值的說明次序有缺省參數的形參必須在形參列表的最后,

30、也就是說缺省形參值的右面不能有無缺省值的參數。因為調用時實參與形參的結合是從左向右的順序。例:int add(int x, int y = 5, int z = 6);/正確int add(int x = 1, int y = 5, int z);/錯誤int add(int x = 1, int y, int z = 6);/錯誤503.3 帶缺省形參值的函數缺省形參值與函數的調用位置如果一個函數有原型聲明,且原型聲明在定義之前,則缺省形參值必須在函數原型聲明中給出;而如果只有函數的定義,或函數定義在前,則缺省形參值需在函數定義中給出。例:513.3 帶缺省形參值的函數int add(int

31、 x = 5,int y = 6) /只有定義,沒有原型聲明 return x + y;int main() add();int add(int x = 5,int y = 6);/原型聲明在前int main() add(); int add(int x,int y) /此處不能再指定缺省值 return x + y;例3-15計算長方體的體積 子函數getVolume是計算體積的函數,有三個形參:length(長)、width(寬)、height(高),其中width和height帶有缺省值。主函數中以不同形式調用getVolume函數,分析程序的運行結果。523.3 帶缺省形參值的函數/

32、3_15.cpp#include #include using namespace std;int getVolume(int length, int width = 2, int height = 3);int main() const int X = 10, Y = 12, Z = 15;cout Some box data is ;cout getVolume(X, Y, Z) endl;cout Some box data is ;cout getVolume(X, Y) endl;cout Some box data is ;cout getVolume(X) endl;return

33、 0;int getVolume(int length, int width/* = 2 */, int height/* = 3 */) cout setw(5) length setw(5) width setw(5) height t;return length * width * height;533.3 帶缺省形參值的函數例3-15(續)3.4 函數重載C+允許功能相近的函數在相同的作用域內以相同函數名聲明,從而形成重載。方便使用,便于記憶。例:54形參類型不同int add(int x, int y);float add(float x, float y);形參個數不同int ad

34、d(int x, int y);int add(int x, int y, int z);注意事項553.4 函數重載不要將不同功能的函數聲明為重載函數,以免出現調用結果的誤解、混淆。這樣不好:int add(int x,int y);int add(int a,int b);編譯器不以形參名來區分int add(int x,int y);void add(int x,int y);編譯器不以返回值來區分int add(int x, int y) return x + y; float add(float x,float y) return x - y; 重載函數的形參必須不同:個數不同或類型

35、不同。編譯程序將根據實參和形參的類型及個數的最佳匹配來選擇調用哪一個函數。例3-16重載函數應用舉例編寫兩個名為sumOfSquare的重載函數,分別求兩整數的平方和及兩實數的平方和。563.4 函數重載#include using namespace std;int sumOfSquare(int a, int b) return a * a + b * b;double sumOfSquare(double a, double b) return a * a + b * b;int main() int m, n; cout m n; cout Their sum of square: s

36、umOfSquare(m, n) endl; double x, y; cout x y; cout Their sum of square: sumOfSquare(x, y) endl; return 0;573.4 函數重載例3-16(續)運行結果:Enter two integer: 3 5Their sum of square: 34Enter two real number: 2.3 5.8Their sum of square: 38.93例3-16(續)3.4 函數重載3.5 使用C+系統函數C+的系統庫中提供了幾百個函數可供程序員使用。例如:求平方根函數(sprt)、求絕對值

37、函數(abs)等。使用系統函數時要包含相應的頭文件。例如:cmath 或 math.h59例3-17 系統函數應用舉例題目:從鍵盤輸入一個角度值,求出該角度的正弦值、余弦值和正切值。分析:系統函數中提供了求正弦值、余弦值和正切值的函數:sin()、cos()、tan(),函數的說明在頭文件cmath中。603.5 使用C+系統函數#include #include using namespace std;const double PI = 3.14159265358979;int main() double angle;cout angle;/輸入角度值double radian = angl

38、e * PI / 180;/轉化為弧度值cout sin( angle ) = sin(radian) endl;cout cos( angle ) = cos(radian) endl;cout tan( angle ) = tan(radian) Visual Studio - Visual C+ - Reference - Libraries Reference -Run-Time Library - Run-Time Routines by Category 633.5 使用C+系統函數3.6.1運行棧與函數調用的執行 形參和局部變量的存儲為什么不能為形參和局部變量分配固定地址?他們僅在函數調用時生效,函數返回后即失效,分配固定地址造成空間浪費更重要的是,發生遞歸調用時,多次調用間的形參和局部變量應彼此獨立需要棧式存儲643.6 深度探索棧棧是一種容納數據的容器數據只能從棧的一端存入(壓入棧)數據只能從棧的同一端取出(彈出棧)653.6 深度探索 3.6.1 運行棧與函數調用的執行ana2a1壓入棧彈出棧棧頂棧底運行棧運

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論