Download presentation
Presentation is loading. Please wait.
1
oop8 function函式
2
Outline 什麼是函式:function? 函式的定義與型別宣告 遞迴式的函式 前置處理器:Preprocessor 標準函式庫
變數等級:storage class
3
什麼是函式:function?
4
函式的重要特性 函式的行為由定義函式的敘述集合決定, 其呼叫、傳引數的方式一定要依定義規範行使。
函式具有一般語言 (如:PASCAL) 的 function 及 procedure 的雙重功能。 函式的定義可以獨立寫成一個原始檔, 並個別編譯後再整體聯結在一起。 使用函式可以使程式更具結構化、更能相互支援、也更易除錯更易維護。
5
函式的定義與型別宣告
6
ANSI 函式定義與宣告
7
函數的定義與宣告 【定義函數的語法】 函數型態 函數名稱 參數列 函數主體 函數型態 函數名稱(資料型態 參數1,資料型態 參數2, …)
函數型態 函數名稱(資料型態 參數1,資料型態 參數2, …) { // 函數主體 [return expression ;] } 函數型態 函數名稱 參數列 函數主體
8
函數的定義與宣告 【呼叫函數的語法】 函數的宣告--函數原型 函數名稱(引數1,引數2, …);
【呼叫函數的語法】 函數名稱(引數1,引數2, …); 函數的宣告--函數原型 函數型態 函數名稱(資料型態 參數1,資料型態 參數2, …);
9
函數範例
10
C++的程式架構 #include < > #define 資料型態 函數1(參數列); // 函數原型,即函數的宣告
資料型態 函數1(參數列); // 函數原型,即函數的宣告 資料型態 函數2(參數列); // 函數原型,即函數的宣告 ... 全域變數的宣告; 資料型態 main(參數列) // 定義main函數 { 私有變數的宣告; 函數主體; return 運算式或值; } 資料型態 函數1(參數列) // 定義函數1 資料型態 函數2(參數列) // 定義函數2
11
變數的能見度 全域(Global)變數 私有(Private)變數 範疇運算子(::)
12
函式的傳回值 return
13
return 的使用例
14
return 的使用例
15
使用函式的注意事項 函式定義時要同時宣告其型別 呼叫函式前要先宣告該函式 傳入函式的引數值, 其型別要與函式原定義一致
接收函式傳回值的變數, 其型別也要與函式一致
16
使用函式的注意事項
17
使用函式的注意事項
18
定義與宣告的區別 函式的宣告是用來宣示函式的名稱、型別, 宣告後 compiler 會建立該函式的相關資料, 而在後來的呼叫時 compiler 才能順利的執行該程式。 函式的定義是程式中一個完整的個體, 用來訂定函式的名稱、引數個數、及函式的內容。函式的定義也具有函式宣告的功能。
19
參數的傳遞 以值傳遞(Call By Value) 以址傳遞(Call By Address)
以參考值傳遞(Call By Reference)
20
以值傳遞(Call By Value) int add(int x, int y) { x += y; return x; }
int i = 789, j = 876 ,r; r = add(80, 90); cout << "add(80,90) = " << r << endl; cout << "add(" << i << "," << j << ") = " << add(i, j) << endl; 【執行結果】 add(80,90) = 170 add(789,876) = 1665 int add(int x, int y) { x += y; return x; }
21
以址傳遞(Call By Address) int add(int *x, int *y) { *x += *y; *y = -(*y);
int i = 789, j = 876; cout << "i = " << i << endl; cout << "j = " << j << endl; cout << "i + j = " << add(&i, &j) << endl; cout << "j = " << j << endl << endl; int add(int *x, int *y) { *x += *y; *y = -(*y); return *x; } 【執行結果】 i = 789 j = 876 i + j = 1665 i = 1665 j = -876
22
以參考值傳遞(Call By Reference)
int i = 789, j = 876; cout << "i = " << i << endl; cout << "j = " << j << endl; cout << "i + j = " << add(i, j) << endl; cout << "j = " << j << endl << endl; int add(int &x, int &y) { x += y; y = -(y); return x; } 【執行結果】 i = 789 j = 876 i + j = 1665 i = 1665 j = -876
23
遞迴式的函式
24
遞迴式的函式
25
遞迴式的函式
26
遞迴式的函式
27
遞迴式的函式
28
遞迴式的函式
29
遞迴式的函式 程式未完, 接下頁
30
遞迴式的函式 接上頁
31
遞迴式的函式
32
遞迴問題範例—河內之塔
33
遞迴問題範例—河內之塔
34
遞迴問題範例—河內之塔 程式未完, 接下頁
35
遞迴問題範例—河內之塔 接上頁
36
遞迴問題範例—河內之塔
37
內嵌(inline)函數 #include <iostream.h>
inline int max(int x, int y); // 將max宣告為inline function void main(void) { int i = 789, j = 876; cout << "max(" << i << "," << j << ") = " << max(i, j) << endl; return; } inline int max(int x, int y) // 將max定義為inline function if (x > y){ return x; else{ return y;
38
遞迴函數(Recursive Function)
cout << "5! = " << factorial(5) << endl; long factorial(int n) { if (n == 1){ return 1; // 當n等於1時同址呼叫 } else{ return n * factorial(n-1); // 當n大於1時呼叫factorial(n-1);
39
主程式的引數 // 程式名稱: 9_func10.cpp // 程式功能: 測試argc, argv
#include <iostream.h> void main(int argc, char *argv[]) { int i; string s[5]; cout << "argc = " << argc << endl; for(i = 0; i < argc; i++){ s[i] = argv[i]; cout << "argv[" << i << "] = " << argv[i] << endl; cout << "s[" << i << "] = " << s[i] << endl; } return; 【執行結果】 D:\PROGRAM>9_FUNC7.EXE abc def argc = 3 argv[0] = D:\PROGRAM\9_FUNC7.EXE s[0] = D:\PROGRAM\9_FUNC7.EXE argv[1] = abc s[1] = abc argv[2] = def s[2] = def
40
前置處理器:Preprocessor C 語言在程式進行編譯之前, 會先將程式中含有 # 記號的部份先行處理, 這個動作我們稱為前置處理 (Preprocess)。 執行前置處理的並不是 compiler, 而是前置處理器。一般都與 compiler 合併在一起。主要有 3 大功能:巨集 (MACRO) 指令、含括 (include) 檔案、和條件式編譯。
41
巨集指令 #define 又稱代換 (Token Replacement) 指令
42
有引數的巨集定義 有引數的巨集定義寫法:
43
有引數巨集的使用例
44
有引數巨集的使用例
45
有引數的巨集與函式的比較
46
利用巨集來除錯
47
利用巨集來除錯
48
#undef 的使用
49
條件性編譯指令
50
條件編譯的使用例
51
條件編譯的使用例
52
標準函式庫 math.h
53
pow() 的使用例
54
stdlib.h
55
time.h
56
time.h 的使用例
57
程式執行的時間 利用 clock() 函式可計算程式執行的時間, 用來評估程式執行的效能。
58
函數的應用 內建函數:亂數產生器rand( ) 與 random(n) 內建函數:日期與時間getdate( ) 與gettime( )
內建函數: ceil(x) 與floor(x) 內建函數: 平方根 sqrt(x) 內建函數: 次方 pow(x, y) 列印空白與列印空白列 布林函數 氣泡浮昇排序法 堆疊的實作(使用陣列) 堆疊的實作(使用鏈結串列結構)
59
變數等級:storage class C 程式的結構與變數等級 內在 (auto) 變數 內在靜態 (static auto) 變數
外在 (external) 變數 靜態外在 (static extern) 變數 函式也是外在個體 register 變數
60
C 程式的結構與變數等級 C 共有:auto、static auto、extern、static extern、及 register 5 種 class, 可以在變數宣告的同時指定其等級。
61
內在變數的視野
62
內在 (auto) 變數 內在變數的生命週期 內在變數的優缺點 區段 (Block) 的構造與視野
63
區段 (Block) 的構造與視野
64
block 中的 auto 變數
65
block 中的 auto 變數
66
內在靜態 (static auto) 變數 static auto 變數是在函式內部定義的。
auto 變數是以堆疊存放的, 必須在函式執行時才會存在, 所以稱為宣告 (declaration)。 但其他如 static auto、extern、static extern 等級的變數, 都是以固定的位址來存放, 而不是以堆疊存放, 在程式編譯時便配置空間, 稱為定義 (definition)。
67
static auto 變數的使用例
68
static auto 變數的使用例
69
外在 (external) 變數
70
外在變數的視野
71
外在 (external) 變數 外在變數的生命週期 外在變數的優缺點
72
外在變數的使用例
73
外在變數的使用例
74
外在變數的使用例
75
外在變數的使用例 程式未完, 接下頁
76
外在變數的使用例 接上頁
77
外在變數的使用例
78
靜態外在 (static extern) 變數
使變數只供單一檔案使用, 即使其它檔案內也定義同樣名稱的變數, compiler 也會把它當成是另一個變數處理, 達到完全 data hiding 效果。
79
靜態外在變數的視野與生命期 靜態外在變數的視野只限於所定義的檔案內, 而其生命期則與一般外在變數相同。
80
靜態外在變數的使用例 程式未完, 接下頁
81
靜態外在變數的使用例 接上頁 程式未完, 接下頁
82
靜態外在變數的使用例 接上頁
83
靜態外在變數的使用例
84
函式也是外在個體 函式要先定義。由函式定義開始至檔案結束的區間為該函式的自然視野。
任何不在函式自然視野內的程式部份, 若想呼叫該函式, 必須先以宣告來拓展函式的視野。 函式的宣告若在呼叫函式內部, 則視野只及於呼叫者本身。
85
函式也是外在個體 函式的宣告若在呼叫函式外部, 則視野由宣告位置開始至檔案結束為止。
不同檔案的程式也可以透過宣告來使用在別的檔案中定義的函式。
86
register 變數
87
前置處理指令
88
#include 【#include 語法】 #include <標準程式庫.h> #include "其他程式.h"
#include <iostream.h> #include "header1.h" #include "C:\cpp\header2.h"
89
#if、#if define與#if !define
... #endif 【#if !define 語法】 #if !define 識別字 // 或 #ifndef 識別字 ... #endif
90
#define 與 #undef 【#define 語法】 #define 識別字 識別字的替代字元或字串 ... #undef 識別字
#include <iostream.h> #define PI #define AREA(r) ((r)*(r)*(PI)) #define MAX(a, b) ((a > b) ? a : b) void main(void) { int r = 5; cout << "AREA(" << r << ") = " << AREA(r) << endl; cout << "MAX(88, 85) = " << MAX(88, 85) << endl; return; }
91
#if、#if define與#if !define
// 程式名稱:10_ifndef1.cpp // 程式功能:#ifndef #include <iostream.h> #define PI #ifndef AREA #include "10_area.h" #endif #define MAX(a, b) ((a > b) ? a : b) void main(void) { int r = 5; cout << "AREA(" << r << ") = " << AREA(r) << endl; cout << "MAX(88, 85) = " << MAX(88, 85) << endl; return; } // 程式名稱:10_area.h // 程式功能:#define AREA(r) #define AREA(r) ((r)*(r)*(PI))
92
程式檔的分割 全域(Global)變數 私有(Private)變數 內部連結 外部連結 static 名稱空間(Namespace)
93
異常處理 【異常處理語法】 try{ // 判斷異常 … throw 運算式/引數/函數 // 丟出異常 }
catch(處理第1種異常型態的參數){ // 補抓異常 // 異常處理 catch(處理第2種異常型態的參數){ // 補抓異常 catch(…){ // 補抓異常
94
異常處理 try{ if (!fin) // 檢查輸入檔fin是否成功開啟 throw "無法開啟輸入檔:"; else
cout << "此行不會被執行\n"; } catch(const char *message){ cout << message << argv[1] << endl;
Similar presentations