Presentation is loading. Please wait.

Presentation is loading. Please wait.

Chap 6 函數 故用兵之法,十則圍之,五則攻之,倍則分之, 敵則能戰之,少則能逃之,不若則能避之。 故小敵之堅,大敵之擒也。

Similar presentations


Presentation on theme: "Chap 6 函數 故用兵之法,十則圍之,五則攻之,倍則分之, 敵則能戰之,少則能逃之,不若則能避之。 故小敵之堅,大敵之擒也。"— Presentation transcript:

1 Chap 6 函數 故用兵之法,十則圍之,五則攻之,倍則分之, 敵則能戰之,少則能逃之,不若則能避之。 故小敵之堅,大敵之擒也。
故用兵之法,十則圍之,五則攻之,倍則分之, 敵則能戰之,少則能逃之,不若則能避之。 故小敵之堅,大敵之擒也。 《孫子兵法﹒謀攻篇 》 函數的使用是模組化程式寫作 (modularized programming) 的重要方式。我們也可以把許多重要的資料處理程序區分出來,分別包裝成函數 (function) 的型式,獨立進行開發和測試,再以呼叫的方式使用,降低程式開發的難度。

2 函數 6.1 函數的基本概念 6.2 以參照的方式呼叫 6.3 inline函數 6.4 變數的適用範圍和生存期間

3 使用函數的目的 減少重複撰寫類似功能的程式 易於除錯和維護

4 函數的語法 呼叫函數 (calling function) 被呼叫函數 (called function) 函數的語法可以分為下列三個部份:
函數的宣告 函數的定義 函數的呼叫

5 範例程式 TempConv.cpp 是一個使用自定函數的簡單程式 (1/3)
#include <math> #include <iostream> using namespace std; // --- 函數C2F () 的宣告 double C2F (double) ;

6 範例程式 TempConv.cpp 是一個使用自定函數的簡單程式 (2/3)
// 主程式 int main () { double CTemp; cout << " 攝氏 華氏 " << endl ; cout << " " << endl ; for ( int i = 1 ; i <= 10 ; i++ ) CTemp = 10.0*i; cout << setw (5) << CTemp << " " << setw (5) << C2F (CTemp) << endl ; } return 0;

7 範例程式 TempConv.cpp 是一個使用自定函數的簡單程式 (3/3)
// 函數C2F () 的定義 double C2F (double C) { double F; F = C*9.0/ ; return F; }

8 程式 TempConv.cpp 操作結果 攝氏 華氏 ------------- 10 50 20 68 30 86 40 104
攝氏 華氏 10 50 20 68 30 86 40 104 50 122 60 140 70 158 80 176 90 194

9 使用函數的示意圖

10 函數原型 函數原型的通式為: 返回資料型態 函數名稱 (參數資料型態列);
其中的小括號()稱為函數呼叫運算子 (function call operator) 以下列出幾種常見的函數原型: int Warning () ; int MaxInt (int, int, int) ; int Area (int width, int Length) ; Area_2 (int, int) ; void Swap (double x, double y) ;

11 函數的定義(definition of a function)
將函數處理資料的細節寫成程式 函數一旦完成定義就可以隨時呼叫使用 不可以把函數的定義置於另一個函數的定義內

12 函數定義的語法 (1/2) 返回資料形態 函數名稱 (參數列) // 函數的標頭列 { 主體敘述 函數的本體 return 傳回值; }

13 函數定義的語法 (2/2) double C2F(double C) // 函數的標頭列 { double F;
F = C*9.0/ ; 函數的本體 return F; } 簡化的函數定義 double C2F(double C){ return C*9.0/ ; }

14 函數的呼叫 可以分為下列兩類: 只用函數名稱及函數呼叫運算子 () 以及呼叫運算子內的引數,自成一個完整的敘述。例如: swap (a, b) ; 將函數的呼叫放在適合該資料型態的敘述中: N = MaxInt (P, q, r) ; M = 2.5 * Area (W,L) ; cout << "Temperature is" << C2F (Temp) << “ Fahrenheit” << endl;

15 傳值呼叫 (call by value): 函數引數的傳遞方式

16 不使用函數原型(prototype)的語法
如果把函數定義置於函數原型的位置 (亦即在main() 之前),則此函數定義就兼具宣告和定義的功能,不需要再使用函數原型

17 範例程式 TempConv2.cpp (不使用函數原型) (1/2)
#include <iomanip> #include <iostream> using namespace std; double C2F (double C) //函數C2F()的定義,兼具宣告的功能 { double F; F = C*9.0/ ; return F; }

18 範例程式 TempConv2.cpp (不使用函數原型) (2/2)
//----- 以下為主程式 int main () { double CTemp; cout << " 攝氏 華氏 " << endl ;   cout << " " << endl ; for ( int i = 1 ; i <= 10 ; i++ ) { CTemp = 10.0*i; cout << setw (5) << CTemp << " " << setw (5) << C2F (CTemp) << endl ; } cout << " " << endl ; return 0;

19 範例程式 SeasonsFnc.cpp: 函數內「return敘述」的功能 (1/2)
#include <iostream> using namespace std; // 以下為函數CheckSeason () 的宣告 void CheckSeason (int) ; // 主程式 int main () { int M; cout << "\n" << "請輸入一個月份 : " << endl; cin >> M; CheckSeason (M) ; return 0; }

20 範例程式 SeasonsFnc.cpp: 函數內「return敘述」的功能 (2/2)
// --- 以下為函數CheckSeason () 的定義 void CheckSeason (int Month) { if (Month < 1 || Month >12) { cout << "您輸入的月份沒有意義!"; return; } cout << "\n" << Month << "月是"; switch ( (Month%12) /3) case 0: cout << "冬季" << endl; break; case 1: cout << "春季" << endl; case 2: cout << "夏季" << endl; case 3: cout << "秋季" << endl; default: cout << "程式有問題!" << endl; } return;

21 參照 (reference) int &M = N; 參照是同一個變數的別名 (alias)
例如: int N; int& M = N; 這裏 & 稱為參照運算子 (reference operator),表示M和N所代表的變數位於同一個位址上。這個定義參照的敘述也可以寫成: int &M = N;

22 範例程式 TempConv3.cpp : 以參照的方式呼叫(call by reference)(1/2)
#include <iomanip> #include <iostream> using namespace std; void C2F (double, double&) ; // 函數C2F () 的原型

23 範例程式 TempConv3.cpp : 以參照的方式呼叫(call by reference)(2/2)
int main () { double CTemp, FTemp; cout << " 攝氏 華氏 " << endl ; cout << " " << endl ; for ( int i = 1 ; i <= 10 ; i++ ) CTemp = 10.0*i; C2F (CTemp, FTemp) ; cout << setw (5) << CTemp << " " << setw (5) << FTemp << endl ; } return 0; // 函數C2F () 的定義 void C2F (double C, double& F) F = C*9.0/ ; return;

24 範例程式 Swap.cpp: 利用參照來交換兩個變數的值 (1/2)
#include <iostream> using namespace std; void Swap (int&, int&) ; void SWAP2 (int, int) ; int main () { int A = 5, B = 10; Swap (A, B) ; cout << "執行過 Swap () \n"; cout << " A 的值是:" << A << "\n B 的值是:" << B << endl; cout << endl; SWAP2 (A, B) ; cout << "執行過 SWAP2 () \n"; }

25 範例程式 Swap.cpp: 利用參照來交換兩個變數的值 (2/2)
// void Swap (int& x, int& y) { int Temp; Temp = x; x = y; y = Temp; } void SWAP2 (int x, int y)

26 程式 Swap.cpp 操作結果 執行過 Swap () A 的值是:10 B 的值是:5 執行過 SWAP2 ()

27 參照的使用限制 參數本身必需改變 要傳回兩個以上的值 有大量參數需要傳遞

28 inline 函數 在編譯時,其程式碼在每個呼叫的地方直接展開加入
Inline函數的定義非常簡單,只要直接在函數的定義前加上關鍵字「inline」就可以

29 範例程式 Inline.cpp: 把函數C2F () 改寫成inline函數 (1/2)
#include <iomanip> #include <iostream> using namespace std; // ---inline 函數 C2F () 的定義 inline double C2F (double C) { return C*9.0/ ; }

30 範例程式 Inline.cpp: 把函數C2F () 改寫成inline函數 (2/2)
// 主程式 int main () { double CTemp; int i; cout << " 攝氏 華氏 " << endl ; cout << " " << endl ; for ( i = 1 ; i <= 10 ; i++ ) CTemp = 10.0*i; cout << setw (5) << CTemp << " " << setw (5) << C2F (CTemp) << endl ; } return 0;

31 inline 函數的使用時機 函數本身非常簡短,但值得包裝起來使用 函數被不同位置呼叫的次數不多時

32 局部變數 (local variables)
在傳值的情況下,每一個函數都佔用自己獨立的記憶體空間,函數內變數的工作空間不會與其他函數的工作空間重疊,這些變數稱為局部變數

33 局部變數的三個儲存種類(storage classes)
auto是所有函數內變數的預設儲存方式,只在函數被呼叫時才存在,該函數結束後就消失 static局部變數並不隨函數呼叫結束而消失,static變數的值保留上一次呼叫結束時的值 register變數可以留在CPU內,提昇函數的執行速度

34 範例程式 Local.cpp: 使用 auto、static 和 register 三種局部變數 (1/2)
#include <iostream> using namespace std; // ---函數 TestLocal () 的宣告 void TestLocal () ; // 主程式 int main () { for (int i=1; i<=3; i++) cout << "第 (" << i << ") 次:" << endl; TestLocal () ; cout << endl; } return 0;

35 範例程式 Local.cpp: 使用 auto、static 和 register 三種局部變數 (2/2)
// --- 函數 TestLocal () 的定義 void TestLocal () { int A = 1; static int S = 1; register int R = 1; cout << " A 的值是 " << A << endl; cout << " S 的值是 " << S << endl; cout << " R 的值是 " << R << endl; for (register int i=0; i<1000; i++) R += 2; cout << " 計算後 R 的值是 " << R << endl; A++; S++; R++; return; }

36 操作結果 第 (1) 次: A 的值是 1 S 的值是 1 R 的值是 1 計算後 R 的值是 2001 第 (2) 次: S 的值是 2
第 (3) 次: S 的值是 3

37 全域變數 如果把變數的宣告放在所有的函數之前,則這些變數值變數稱為全域變數 (global variables) 可以讓其後的所有函數共用

38 範例程式 Global.cpp 檢查全域變數的特性 (1/2)
#include <iostream> using namespace std; int GLOBAL = 1, GLOBAL_2 = 7; //全域變數 // 函數 TestFnc () 的宣告 void TestFnc () ; // 主程式 int main () { int Local = 3; // 局部變數 GLOBAL = 9; cout << "GLOBAL 的值原來是:" << GLOBAL << endl; cout << "Local 的值原來是:" << Local << endl; cout << endl; TestFnc () ; cout << "呼叫 TestFnc () 之後." << endl; cout << "GLOBAL 的值目前是:" << GLOBAL << endl; cout << "Local 的值目前是:" << Local << endl; return 0; }

39 範例程式 Global.cpp 檢查全域變數的特性 (2/2)
// ---函數 TestFnc () 的定義 void TestFnc () { int Local = 2; // 與主程式內變數同名的局部變數 int GLOBAL_2 = 20; // 與全域變數同名的局部變數 Local += 10; GLOBAL += 10; cout << "GLOBAL_2 的值是:" << GLOBAL_2 << endl; cout << "::GLOBAL_2 的值是:" << ::GLOBAL_2 << endl; cout << endl; }

40 操作結果 GLOBAL 的值原來是:9 Local 的值原來是:3 GLOBAL_2 的值是:20 ::GLOBAL_2 的值是:7
呼叫 TestFnc () 之後. GLOBAL 的值目前是:19 Local 的值目前是:3

41 extern 和 static 兩種全域變數 extern全域變數:宣告這個變數已經在其他檔案內定義過了

42 範例程式 ExtrenA.cpp : 探討各種全域變數儲存種類的特性 (1/3)
// ExternA.cpp #include <iostream> using namespace std; int Am, An; // 全域變數 static int ASx, ASy; // static全域變數 // --- 函數的宣告 void Func1 () ; void Func2 () ; void Func3 () ;

43 範例程式 ExtrenA.cpp : 探討各種全域變數儲存種類的特性 (2/3)
// 主程式 int main () { cout << "執行過 Func1 () \n"; Func1 () ; cout << "Am 的值是:" << Am << endl; cout << "An 的值是:" << An << endl; cout << endl; cout << "執行過 Func2 () \n"; Func2 () ; cout << "執行過 Func3 () \n"; Func3 () ; return 0; }

44 範例程式 ExtrenA.cpp : 探討各種全域變數儲存種類的特性 (3/3)
extern int Bp; // extern 變數 //----- 函數 Fnc3 () 的定義 void Func3 () { cout << "Bp 的值是:" << Bp << endl; cout << endl; }

45 範例程式 檔案 ExternB.cpp // ExternB.cpp int Bp; // 全域變數
extern int Am; // extern變數 // --- 函數 Fnc1 () 的定義 void Func1 () { Bp = 2; Am = 8; } // --- 函數 Fnc2 () 的定義 void Func2 () extern int An; Am += 10; An = 27;

46 操作結果 執行過 Func1 () Am 的值是:8 An 的值是:0 執行過 Func2 () Am 的值是:18 An 的值是:27
Bp 的值是:2


Download ppt "Chap 6 函數 故用兵之法,十則圍之,五則攻之,倍則分之, 敵則能戰之,少則能逃之,不若則能避之。 故小敵之堅,大敵之擒也。"

Similar presentations


Ads by Google