二進位也可以很有趣

http://www.csie.nctu.edu.tw/~tsaiwn/oop/
02_oop.ppt
Review: C++物件導向程式設計 1/3
Introduction to C++ with OOP
蔡文能
[email protected]
[email protected]
交通大學資訊工程學系
2007/07/13 Friday
1
交通大學資訓工程學系 蔡文能
Agenda
1/3
1.
2.
3.
4.
2/3 5.
6.
7.
3/3 8.
9.
From C to C++ (C++ == a better C + Objec-Oriented support)
a. I/O stream, b. pass-by-reference c. function name overloading,
d.operator overloading, e. default parameter, f.inline function,
g. template function
Data Abstraction: Why using struct? Why using class?
An ADT example: How to design/construct/use a Stack?
Introduction to OOA, OOD, and UML
Inheritance and examples: Animal and Mankind, Vector and Stack
virtual function and Polymorphism: How it works?
Generic programming: template function/class, and STL
Exceptions: Scope of exceptions, raising exception, exception handlers
More tips about class and ADT: a. constructor/Destructor, b. class
members vs. instance members, c.friend and access control of class
members
2
http://www.csie.nctu.edu.tw/~tsaiwn/oop/
交通大學資訓工程學系 蔡文能
From C to C++
• C++ 最重要的當然是 class (類別)
• C++ 除了 class 外還有一些雕蟲小技
– I/O stream facility and other Class Library
– Parameter passing? (C++可指定call by reference)
– function name overloading (函數名稱重複使用)
– Operator overloading, … 
n= 5+38; x=
25.8+3.69;
– inline function ? (只影響編譯與執行效率, 不影響答案)
– template function, template class, …
3
交通大學資訓工程學系 蔡文能
C++ Input/Output Stream
read(0, …); write(1, …); write(2, …); /* system call */
• In C,
– fscanf(stddin, …); fprintf(stdout, … ); fprintf(stderr, …);
printf("Enter new yy: "); /* where yy is a float */
scanf("%f", &yy); /* what if yy is a double? */
printf("The new yy is: %f\n", yy);
• In C++, I/O devices 用起來像 Object (物件)
cout << "Enter new yy: ";
cin >> yy;
cout << "The new yy is : " << yy << endl;
• In Java, System.out.print("The answer is " + ans + "\n" );
4
交通大學資訓工程學系 蔡文能
C and C++ I/O compared
C-style I/O:
• No type safety. What happens with printf(“%d”, ‘c’);?
• Conversion specifications have a high learning curve.
• Almost all the state of the I/O is contained in the function call.
C++ style I/O:
•
Manipulators are very verbose/annoying
•
Global state gets changed. When you do “cout << 2.4555”, what
precision are you set at? You don’t know.
• You get more customizability since C++ I/O is classed based.
NEVER mix C and C++ I/O...until you know what
ios::sync_with_stdio() does.
5
交通大學資訓工程學系 蔡文能
Pass-By-Reference
• A reference parameter in a function "references" the same physical
memory location as the argument passed in
• Changing the value of a reference parameter:
– Does not change the memory associated with the parameter
– Does change the memory associated with the argument passed in
– Therefore – argument's memory must not be constant or literal
void refFunc(float &val)
{
val = 50;
}
This assignment changes the memory
associated with this variable!
int main()
{
int mainVal = 9;
refFunc(mainVal);
cout << "mainVal: " << mainVal << endl;
return (0);
}
mainVal: 50
6
交通大學資訓工程學系 蔡文能
參數傳遞(parameter passing) ?
/* 寫一個函數可以將傳入的兩整數參數對調*/
/* 函數如何寫? */
return_type function_name( parameters ) { local variables; statements; }
/* 如何叫用? */
function_name( actual arguments ) ;
C語言參數是pass by value
C++語言參數則可以pass by Reference
不過, 這違反了C的設計者所謂的“怎麼宣告就怎麼用”; 例
如:看到 int *x ; 所以 *x 就當 int 來用! 而 x 則是 int* ; 就是
說 x 是一個指向整數的指標!
7
交通大學資訓工程學系 蔡文能
參數(parameter)傳遞
(錯)
/* 寫一個函數可以將兩整數對調, wrong version */
#include<stdio.h>
void swap( int x, int y) {
(錯)
int temp;
temp=x;
x = y;
因為C語言參數是pass by value
y = temp;
}
int m=38, n=49;
int main( ) {
(錯)
swap(m, n); /* 沒有用的! 回來後m, n 不變 */ (錯)
printf("m=%d, n=%d\n", m, n);
}
8
交通大學資訓工程學系 蔡文能
參數會被函式改變的傳遞法 (正確)
/* 寫一個函數可以將兩整數對調, correct version */
#include<stdio.h>
void swap( int * x, int* y) { /* 注意參數寫法 */
int temp;
注意不要在temp左邊寫星號, 意思不同
temp = *x;
參考K&R課本5.2節
*x = *y;
*y = temp;
}
/* 註: C++ 則有 pass by reference 寫法 */
int m=38, n=49;
Call by address to pointer
int main( ) {
swap(&m, &n); /* 注意 &m和&n把address傳過去 */
printf("m=%d, n=%d\n", m, n);
}
&m, &n : address of m 和address of n
9
交通大學資訓工程學系 蔡文能
Call by Reference參數傳遞 (C++專有)
/* 寫一個函數可以將兩整數對調, in C++ */
#include<stdio.h>
void swap( int & x, int & y) {
int temp;
C++才可以用pass by Reference
temp=x; x = y; y = temp;
}
int m=38, n=49;
前面所說的 C language 可用
之方法仍可以用於 C++.
int main( ) {
swap(m, n); /* 注意! 看起來好像不會變 */
printf("m=%d, n=%d\n", m, n);
}
10
交通大學資訓工程學系 蔡文能
Function name Overloading
(C++專有)
/*寫個函數可將兩 int數對調, 再寫一個函數可以將兩double數對調, 名稱? */
#include<stdio.h>
void swap( int & x, int & y) { /* by reference */
int temp;
temp=x; x = y; y = temp;
}
void swap( double & x, double & y) {
double temp;
temp=x; x = y; y = temp;
}
C++允許同名的 function, 但注意參數 11
交通大學資訓工程學系 蔡文能
C++ STL 中的 swap( )是 template
template <class T>
void swap( T & x, T & y) {
T temp;
temp=x; x = y; y = temp;
}
此即所謂的 template function (樣版函數)
STL = Standard Template Library
交通大學資訓工程學系 蔡文能
12
再談 function name overloading
 Function name overloading 不一定在class內! 請注意
它與 Object Oriented 並沒有關係!
 function name overloading 是指很多個函數都用同一個
名稱
例如:
int m=2, n=3;
double x=3.8, y=4.9;
swap(m, n); C++允許同名的 function, 但注意參數
swap(x, y);
顯然以上兩個 swap 應該是不同函數, 這是由它們的參數不同得知的!
這在 compile time 就可以決定是用哪一個 swap, 此稱之為
static binding (靜態繫結)! 如何做? (next slide)
? 何謂 dynamic binding? (next slide)
13
交通大學資訓工程學系 蔡文能
C++ How to …overloading/polymorphism
 C++ 到底是用了什麼技術辦到 function name
overloading ? 事實上只是用了一個超級簡單的 idea:
– C++只是把參數的型別納入函數名稱中而已,
Compiler會偷換 function name, 參數的type也變成
function_name 的一部份: ( static binding)
例如: void swap(int&, int&); 會被譯為(可能!):
__swap_F2RiRi
 如何達成 polymorphism ?
 透過 virtual function  dynamic binding
 p-> draw( ); 譯成去執行 p 指過去之物件內
有個指標指過去的函數表中draw的項目位置指過去
的那個函數! (相關指標在 new 出物件時填入)
14
交通大學資訓工程學系 蔡文能
Tips about Dynamic binding
 Dynamic binding(動態繫結)是指在 執行階段
(run time) 才確定!
 動態繫結是一種被 Compiler 使用的技術, 它也
不是 OO 才有的, C語言的 Auto 變數(函數中沒
有宣告 static 的 Local 變數)就是使用Dynamic
binding;在執行期(Run time)時才安排於堆疊
(Stack)中!
Static binding? vs. Dynamic binding?
15
交通大學資訓工程學系 蔡文能
Operator overloading (1/4)
• Operator overloading
– Use traditional operators with user-defined objects
– A straightforward and natural way to extend C++
– Requires great care
• When overloading misused, program difficult to understand
• Format of the operator function
– Function name is keyword operator followed by the
symbol for the operator being overloaded.
– operator+ would be used to overload the addition
operator (+)
16
交通大學資訓工程學系 蔡文能
Operator overloading (2/4)
• You can NOT invent operator
– No new operators can be created, use only existing
operators
• Arity (number of operands) canNot be changed
– Unary operators remain unary, and binary operators remain binary
– Operators &, *, + and - each have unary and binary versions
• Unary and binary versions can be overloaded separately
• Can NOT overload operators for Built-in types
– You cannot change how two integers are added
17
交通大學資訓工程學系 蔡文能
Operator overloading (3/4)
• Operator functions
– Can be member or non-member functions (i.e., friend)
– Operator functions for the assignment operators must be a member
function
– i.e: (), [], ->,=
• Member function vs. non-member function
– Leftmost operand must be an object (or reference to an object) of the class
– If left operand of a different type, operator function must be a nonmember function
– A non-member operator function must be a friend if private or
protected members of that class are accessed directly
18
交通大學資訓工程學系 蔡文能
Operator overloading (4/4)
• Overloaded binary operators
– Non-static member function, one argument
– Non-member function, two arguments
– Leftmost operand must be an object (or reference to an
object) of the class
– If left operand is an object of a different type, operator
function must be a non-member operator function
– A non-member operator function must be a friend if
private or protected members of that class are
accessed directly
19
交通大學資訓工程學系 蔡文能
Operators in C / C++ / Java(1/3):
Operator
C
C++
Java
::
Scope res.
. -> [] ()
. -> [] ()
sizeof
n/a n/a []
() n/a
Unary ops, address, - ! ++ -dereference, cast,
& * () n/a
allocate, deallocate n/a
- ! ++ -& * () new
delete
- ! ++ -n/a n/a ()
n/a n/a
Multiply, divide, mod * / %
* / %
* / %
Member selection,
subscripting,
function call, sizeof
Add, subtract
+ -
+ -
+ -
Shift
<< >>
<< >>
<< >>
20
交通大學資訓工程學系 蔡文能
Operators in C / C++ / Java (2/3):
Operator
C
C++
Java
relational
< <= > >= < <= > >= < <= > >=
equality
== !=
== !=
== !=
bitwise AND
&
&
&
bitwise XOR
^
^
^
bitwise OR
|
|
|
logical AND
&&
&&
&&
logical OR
||
||
||
21
交通大學資訓工程學系 蔡文能
Operators in C / C++ / Java (3/3):
Operator
C
C++
Java
conditional
? :
? :
? :
assignment
= *= /=
%= += -=
<<= >>=
&= != ^=
= *= /=
%= += -=
<<= >>=
&= != ^=
= *= /=
%= += -=
<<= >>=
&= != ^=
throw
exception
sequencing
,
,
,
22
交通大學資訓工程學系 蔡文能
Operator Overloading Examples(1/3)
• As a member function ( 寫成自己人)
class Haha {
public:
const Haha &operator+=( const Haha & p) const {
/*** mutable member 是例外 ***/
}
//...
};
Haha x, y, z; // …
表示不會改 member data,
// then:
此例顯然不該寫這個 const, Why?
y += z;
// equivalent to
y.operator+=( z ); //operator+= is a member
23
交通大學資訓工程學系 蔡文能
Operator Overloading Examples(2/3)
• As friend function (不好, 但文法正確)
class Haha {
public:
friend const Haha &operator+=( Haha&, const Haha & ) ;
//...
};
const Haha& operator+=(Haha&x, const Haha&y){ /*…*/ }
Haha x, y, z; // …
// then:
y += z;
// equivalent to
operator+=( y, z ); // operator+= is a friend
operator+= 應寫成自己人比較好
交通大學資訓工程學系 蔡文能
24
Operator Overloading Examples(3/3)
• As friend function again (可以, 很好)
class Haha {
long data_;
public:
friend ostream& operator<<(ostream&, const Haha & ) ;
//...
};
ostream& operator<<(ostream&river, const Haha&y){
river << y.data_; /*…*/ }
Haha x; // …
// then:
cout << x;
// equivalent to
operator<<( cout, x); // operator<< is a friend
Operator<< 一定要寫成朋友! 無法寫成自己人! Why?
交通大學資訓工程學系 蔡文能
25
Default parameter
void setNum(int x = 3388);
void setNum(int x) {
cout << "You gave me " << x << endl;
// …
}
setNum(123);
setNum( ); /* compiler 會自動填入 3388 */
setNum(456);
26
交通大學資訓工程學系 蔡文能
inline Functions
 Inline function is an important addition to C++ because it
can allow you to create very efficient code.
 They are especially important in classes, because a lot of
functions, such as the constructor or accessors are executed
very often.
 Inline is actually just a request to the compiler, not a
command. (eg. recursive functions often not set inline)
 inline functions = faster processing – larger code size
寫了 inline 的函數, 用到時用展開的(類似 macro), 不是譯成呼叫;
 在 class內就寫完的function會自動變 inline function; 在 class 之外
寫的 function 要寫明 inline 才是 inline function. (C99 也可用)
只要在原來 function 之前面寫 inline, 就可能使得 function 變成 inline function.
這是要求 Compiler 採用類似 Macro (巨集) 展開方式來翻譯該函數呼叫!
所以通常機器碼較佔空間, 但執行起來比較快 (用空間換時間);但是它
仍然具有 function 的效果!
注意: 含有某些 statements 的functions無法成為 inline, compiler會把關!
27
交通大學資訓工程學系 蔡文能
template function
template <class T>
void swap( T & x, T & y) {
T temp;
temp=x; x = y; y = temp;
}
int a=38, b=49, m=123, n=456;
double x=23.5, y = 33.88;
swap( a, b); /* 會生出一份 swap function */
swap(x, y);
swap(m, n); /* 不會再生出一份 function */
swap( ) in STL (Standard Template Library)
交通大學資訓工程學系 蔡文能
28
再 談 變數
Variable 變 變 變
• 變數當然會變才叫變數 – 廢話!
– 變數命名規則與慣例? averageScore, n, x
• 變數放在電腦的記憶體 – 何處?
– 與程式一起, 與程式分離? –由Linker 負責
– 堆疊區 (STACK) ?  嘿洗蝦密碗糕啊?
• 變數的能見範圍(Scope)? 或說有效範圍
– 函數(函式 )內的變數:Local variable 局部(區域)變數
– 函數外的變數: Global variable整體變數
• 變數何時生出?何時死掉? 生命期 (Life time) ?
29
交通大學資訓工程學系 蔡文能
變數分類
• 依能見範圍(Scope, 或說有效範圍)?
– Local 區域 vs. Global 整體
• 依何時給它記憶體位置 (稱作binding)
– Static variable : 靜態變數, Run 之前 (compile / Link)
– Dynamic variable: 動態變數, Run 之後才會做
binding(就是Run 之後才給它位置)
• 自動要自動還: auto 變數 (function內沒寫static)
• 手動要: 使用malloc 或 calloc 要, 用free還 (C++用new 和
delete)
• auto 變數被安排在 stack (堆疊)
• 手動要的(malloc, calloc)在 Heap (堆積)
30
交通大學資訓工程學系 蔡文能
變數 (Variable) 的 Scope, Life time
• 變數的能見範圍(Scope, 或說有效範圍)
– 函數(函式 )內的變數:Local variable 局部(區域)變數 :
只有在函數內有效
– 函數外的變數: Global variable (整體變數)
– Global variable : 宣告之後就一直有效
• 變數生命期 (Life time) ?
– 靜態變數從程式開始 Run 就“出生”
– Auto 變數在進入函數時生出, 離開函數時死掉(把記
憶體還給系統)
– 沒有宣告 static 的:Local變數就是Auto 變數
31
交通大學資訓工程學系 蔡文能
Global 變數 vs. Local變數 (1/2)
#include <iostream.h>
int x = 38, y=250; /* Global */
void sub1(int); /* 見後面程式 */
int main( ) {
int x=49; /* Local */
sub1(::x); /* Global 的 x == 38 */
sub1(x); /* Local 的 x == 49 */
cout << "x=" << x << endl;
cout << "outside x=" << ::x << endl;
cout << " y=" << y << endl;
return 0; /* 0 in main( ) means OK */
}
交通大學資訓工程學系 蔡文能
32
Global 變數 vs. Local變數 (2/2)
void sub1(int y){
cout << "y=" << y << endl;
x++;
/* Global 的 x , 因為 Local 沒有 x*/
::x++; /* 也是 Global 的 x */
y++;
/*因為y是 pass by value, 回去不會變*/
::y++; /* 是 Global 的 y */
return ; /* 不寫也可以 */
}
pass by value 就是 call by value
講法不同而已 
交通大學資訓工程學系 蔡文能
33
Static Local變數
(1/2)
#include <iostream.h> // #include<iostream>
int fa( ) {
int x = 1;
return x++; /*先取其值, 再做 ++ */ }
int fb( ) { static int x = 1; /* 注意 static int x = 1; */
return x++; }
int main( ) {
cout << "fa( )=" << fa( )<<fa( )<<fa( ) << endl;
cout << "fb( )=" << fb( )<<fb( )<<fb( ) << endl;
return 0; /* 0 in main( ) means OK */
}
return x++; 和 return ++x; 不同 ! 34
交通大學資訓工程學系 蔡文能
Static Local變數
(2/2)
int fa( ) {
int x = 1;
return x++; /*先取其值, 再做 ++ */
}
int fb( ) {
static
// 把 static 寫在下列左方也一樣
int x = 1;
// 注意 static int x = 1;
return x++;
}
35
交通大學資訓工程學系 蔡文能
Static Local變數 , evaluation 順序
#include <stdio.h>
int fa( ); /*宣告*/
int fb( );
int main( ) {
/* 不同系統可能不同答案*/
printf( "fa( )=%d %d %d \n",
fa( ), fa( ), fa( ) );
printf( "fb( )=%d %d %d \n",
fb( ), fb( ), fb( ) );
return 0; /* 0 in main( ) means OK */
}
// int fa( ) … 也可以寫在另一個檔案內
36
交通大學資訓工程學系 蔡文能
Evaluation 順序
#include <stdio.h>
int gg(int x){
static ans=0;
ans = x + ans*ans; return ans;
}
int main( ) {
/* 不同系統可能不同答案 !*/
int haha = gg(1) + gg(2) + gg(3); /*先做哪個gg( )
printf("haha=%d\n", haha);
return 0;
}
?*/
expression中有多個函數叫用會先做哪個 gg( )?
C/C++ 沒有規定! 所以看寫 compiler的人高興37
交通大學資訓工程學系 蔡文能
Auto 變數不可佔太多memory
•Auto 變數就是沒寫 static 的 Local 變數
•Auto 變數是在進入函數時才在STACK區安排記憶體,
在離開函數(return)時就還掉(改變 Stack Pointer)
•STACK區一般不會很大(幾十 K Bytes)
–
–
–
–
Auto 變數用STACK區, 所以太大的array不能用
叫用函數時, return address 也會被推入 STACK
參數傳遞也是用 STACK區
C/C++推入參數時是先推入最後一個參數, 這使得第一
個參數會在堆疊的最上方, 進入函數時, STACK中
return address 之下就是第一個參數
– C/C++離開函數時, 函數不負責拿掉STACK中 的參數,
那是叫用函數那個程式的責任! (與其它語言不同)
38
交通大學資訓工程學系 蔡文能
Auto 變數佔用STACK區memory
•Auto 變數就是沒寫 static 的 Local 變數
address 0
Instruction
Pointer
CPU
IP
SP
系統區
程式+靜態data
HEAP堆積
malloc( ), new( )
Stack
Pointer
Heap 由上往下長
Stack 由下往上長
交通大學資訓工程學系 蔡文能
STACK
(參數與Auto變數)
系統區
39
Static變數?
•Global 變數都是static 的 變數
•Local 變數就是寫在函數內的變數
– 有補 static 修飾詞則為 static變數 (靜態變數)
– 沒有補 static 修飾詞則為 Auto 變數 (自動變數)
•static 的 變數在程式開始 RUN 之前就存在, 且已經
設好初值, 程式結束後才會還掉所佔記憶體(生命期)
•寫了 extern 表示只是 宣告(declare), 不是定義(define)
•Local 變數就只能在該函數(function)內存取(access)
•Global 變數則只要看得見它的任一函數都能存取它
– 宣告之後就看得見, 沒宣告就定義 則看作 同時宣告了
•注意 main( ) 也是函數, 沒有特別偉大! 應寫成 int function.
40
交通大學資訓工程學系 蔡文能
Global, Static Local, Auto 變數
#include <stdio.h>
extern int x; /* 只有宣告 , 還不知道位置在何處?*/
寫了 extern 表示只是 宣告, 不是定義(define)
int fa( ) ;
int fb( ) { int ans=0; return ++ans; }
int main( ) {
int kk=123;
cout << "fa( )=" << fa( )<<fa( )<<fa( ) << kk<<endl;
cout << "fb( )=" << fb( )<<fb( )<<fb( ) << endl;
return 0; /* 0 in main( ) means OK */
}
int x, y; /* 真的 x 在這, 也可以寫在另一個 file 中*/
int fa ( ) { /*…* }
41
交通大學資訓工程學系 蔡文能
Static Global 變數
#include <stdio.h>
Information Hiding?
#define BUFSIZE 100
static char buf[BUFSIZE];
static int bufp = 0;
Functions in another
int getch( ) {
file can NOT see
/* . . . */
these
static variable
}
void ungetch(int c) {
/* . . . */
也參考stack的push和pop寫在同一獨
}
立 file 中, push和pop共享 data
交通大學資訓工程學系 蔡文能
42
再談Static Global 變數
#include <stdio.h>
Information Hiding?
#define RAND_MAX 65535
static unsigned long seed=0; /* global */
只有rand 和srand 看得見 seed
int rand( ) {
seed = seed * 1103515245 + 12345;
return seed % (RAND_MAX+1);
}
void srand(int newseed) {
seed = newseed;
}
交通大學資訓工程學系 蔡文能
程式庫中的
Pseudo Random Number
Generator (PRNG)
43
register 變數 , volatile 變數
#include <stdio.h>
enum {BUFSIZE=100, NSTU=60};
register int wrong; /* this is wrong, global不可*/
volatile int haha;
void myfun(register int x ) {
register int yy, i; /* OK */
int * p;
拜託Compiler儘可
能安排在CPU內
/* . . . */
的暫存器
p = &yy; /* this is wrong */
}
參考K&R課本4.7節 44
交通大學資訓工程學系 蔡文能
volatile 變數
#include <stdio.h>
volatile int haha ; /* tell compiler … */
警告Compiler這
int main( ) {
變數可能會被別
int k; double ans;
的程式改變
for(k=1; k<=99; ++k) { /* . . . */
ans = haha * haha; /* do NOT optimize*/
printf(" ans=%f\n ", ans);
}
}
參考K&R課本4.7節 45
交通大學資訓工程學系 蔡文能
ADT --- Data Abstraction
• An Abstract Data Type (ADT) is a user-defined
data type that satisfies the following two
conditions: (Encapsulation + Information Hiding)
– The representation of, and operations on, objects of the
type are defined in a single syntactic unit; also, other
program units can create objects of the type.
– The representation of objects of the type is hidden
from the program units that use these objects, so
the only operations (methods) possible are those
provided in the type's definition which are known as
interfaces.
46
交通大學資訓工程學系 蔡文能
ADT in C_plus_plus
class / struct can be used as the encapsulation
device. (只有一開始default access屬性不同)
All of the class instances of a class share a
single copy of the member functions.
Each instance of a class has its own copy of
the class data members (except static data)
Instances can be static, stack dynamic (auto), or
heap dynamic; this is similar to built-in types.
class instance of a class = Object
Object is an instance of some class
交通大學資訓工程學系 蔡文能
47
C++ = a better C + classes
• Why using struct in C ?
– Group related data together (後面講)
• C++ 最重要的就是 class (類別)
– class 其實是 struct 的延伸
– In C++, we can put related functions with the
related data in struct ( class )
– 所以 C++ 的 class 就是 C 的 struct 加上一些
規定
– Java 把 struct 拿掉了! 且 union 也沒了!
• class 有何用? (後面講)
48
交通大學資訓工程學系 蔡文能
Object Oriented Concept (1/3)
• Why using class ? (先考慮 why using struct ?)
– 支援 OOP (物件導向Object Oriented Programming)
– 又譯作 個體導向程式設計
– 考慮 Stack 堆疊 : 讓東西用起來更像東西
• ADT (Abstract Data Type)
– 把 data 以及對 該些 data 有關的方法(method)
或稱函數(function, 函式)封裝(encapsulate)在一
個程式單元方便使用
49
交通大學資訓工程學系 蔡文能
Object Oriented Concept (2/3)
• Object-Oriented Analysis (OOA)
– Goal: Understand the domain
• Object-Oriented Design (OOD)
– Goal: Design a solution, a model of the domain in
which the desired activities occur
• Object-Oriented Programming (OOP)
– Goal: Implement the solution
• Note: A Good Design is 2/3 Before You Hit the
Keyboard
50
交通大學資訓工程學系 蔡文能
Object Oriented Concept (3/3)
// 如何讓 Stack(堆疊) 用起來更像在使用物件
// 或者說像在使用零件(Component, 軟體IC)
int main( ) {
Stack xo;
/* xo is an object, it is a Stack */
xo.push(880);
/* 要求 xo 把 880 push 進去 */
xo.push(770);
xo.push(53);
while(! xo.isempty( ) ){
cout << " " << xo.pop( ); /* 要求 xo 吐出頂端元素 */
/* .. .. .. */
} cout << endl;
How?
return 0;
如何製作 Stack?
}
51
交通大學資訓工程學系 蔡文能
Take a Break (10 min.)
不要跑掉
[email protected]
蔡文能
52
交通大學資訓工程學系 蔡文能
問題與思考 (如何自定資料結構?)
Why using struct ?
• 只能用char, int, float, double 等這些
data type 嗎?
• User defined data type?
•考慮寫程式處理全班成績資料, 包括加總平均
並排序(Sort)然後印出一份照名次排序的全部
資料以及一份照學號排序的全班資料
–如何做 Sort (排序) ?
–Sort 時兩學生資料要對調, 要如何對調?
–有很多 array ? 存學號的 array, 存姓名的
array? 存成績的 array? … 萬一忘了一個array?
Bubble sort, Insertion sort, Selection sort
交通大學資訓工程學系 蔡文能
53
So, Why using struct?
• struct 可以把相關資料 group 在一起
struct Student x[99], tmp;
/* … */
tmp = x[i];
x[i] = x[k];
x[k] = tmp;
• 增加程式可讀性
• 程式更容易維護
struct Student {
long sid;
char name[9];
/* … */
}; /* 注意 “;” 分號 */
struct Student yy;
C++ 與 C99 可以不寫 “struct” 這字; C 須用 typedef
交通大學資訓工程學系 蔡文能
54
C 須用 typedef 才可不寫struct
typedef
struct Student {
long sid;
char name[9];
/* … */
} Student_t; /* 注意 “;” 分號 */
struct Student yy;
Student_t stemp; // stemp 也是 Student
一般建議: user-defined data type 用大寫字母開頭!
55
交通大學資訓工程學系 蔡文能
What is Object? Class? (1/2)
• object 就是“東西”, 就是以前的“變數”
• class 就是“類別”, 某種東西的型別
int m, n; /* int 是整數類別 */
/* m, n 都是變數 */
Student x, y; /* Student 是我們自訂類別 */
/* x, y 都是 object */
56
交通大學資訓工程學系 蔡文能
What is Object? Class? (2/2)
• object is an instance of some class
• 文法上, C++的class 就是以前的 struct
class Student { public:
/* …與寫 struct 同 */
};
struct Node { private:
/* …與寫 class 同 */
};
57
交通大學資訓工程學系 蔡文能
Class 與 struct 文法上?
struct Student{
long sid;
char name[9];
};
Student x, y[99], tempstu;
可以使用 x.sid
y[3].sid = tempstu.sid;
class Student { // private:
long sid;
char name[9];
};
Student x, y[99], tempstu;
不可以使用 x.sid 等等
Why ??
Information hiding
58
交通大學資訓工程學系 蔡文能
用 array 來做 STACK
•
void push (int y) {
++sptr;
x[sptr] = y;
}
Initialization:
sptr = -1; /*empty*/
(1/2)
int x[99];
98
sptr
push (456) ;
push (3388) ;
Stack
Pointer
int ans = pop( );
int sptr;
3388
456
需要一個array 和一個整數
1
0
-1
int pop ( ) {
int tmp=x[sptr];
--sptr;
return tmp;
}
59
交通大學資訓工程學系 蔡文能
用 array 來做 STACK (2/2)
static int x[99]; /* 別的檔案看不到這*/
static int sptr = -1; /* empty stack */
void push(int y) {
++sptr;
/* move stack pointer */
x[sptr] = y; /* put the data y there */
}
int pop( ) {
return x[sptr--]; /*注意 -- 寫後面*/
}
/* 其它相關 function例如 isempty( ) */
60
交通大學資訓工程學系 蔡文能
使用 STACK
extern void push(int); /*宣告*/
extern int pop( );
#include <stdio.h>
int main( ) {
push(543);
push(881);
printf("%d\n", pop( ) );
}
/* 可以用! 但若要兩個 Stack 呢? */
61
交通大學資訓工程學系 蔡文能
More about STACK (1/3)
/* 若要兩個 Stack 呢? */
解法之一
==> 使用兩個 array, 並把 array 當參數
push(ary2, x);
ans = top(ary2);
但是這樣該些 array 必須 開放讓使用者知道
 要讓宣告 extern就看得到, 不可再用 static Global
 違反不必讓使用者知道push到哪去的 Information
Hiding 原則 !
(或是該些 array 要定義在使用者程式裡面,
更不好!)
62
交通大學資訓工程學系 蔡文能
More about STACK (2/3)
/* 若要兩個 Stack 呢? */
解法之二 (better, but NOT good enough!)
==> 整個檔案複製到另一個 file, 並把 各相
關函數名稱都改掉, 例如 push2,
pop2, …
==> array 與變數名稱都不用改! Why?
(因為 static Global 使其它file中function看不見)
但是這樣 也不是很方便, 函數名稱一大堆
 若要三個 Stack 呢? 四個呢? …
(不過這比前面使用不同 array 的方法好!)
交通大學資訓工程學系 蔡文能
63
More about STACK (3/3)
/* 若要兩個 Stack 呢? */
/* 若要三個 Stack 呢? 四個? 五個 . . . */
/* 有沒有更方便直接的方法? */
solution ==> using C++ Class
to define a Stack as a Software Component
(軟體元件或零件)
Stack x;
Stack y;
x.push(13579);
y.push(258);
y.push( x.pop( ) );
64
交通大學資訓工程學系 蔡文能
Stack -- class example ( 1/2) mystk.h
class Stack {
// private:
long data[99]; /* 直接寫 99 不是好習慣*/
int sptr;
標準程式庫的堆疊是stack
public:
注意是小寫! 且其 pop( )是 void
Stack( ) ; /* constructor */
void push( long );
標準程式庫是empty
long pop( );
bool isempty( );
}; /* class Stack */
bool 要新版的 C++ 才有, 如果不能用就改用 int
交通大學資訓工程學系 蔡文能
65
Stack -- class example (2/2) mystk.cpp
#include "mystk.h"
#include <iostream.h>
Initialization 工作
要寫在特殊函數
Stack::Stack( ) { sptr = -1; } /*Constructor*/
void Stack::push( long xx) { /*注意 Stack:: */
data[ ++sptr ] = xx;
}
long Stack::pop( ) {return data[sptr--];}
bool Stack::isempty( ) { return sptr == -1;}
// . . .
bool 要新版的 C++ 才有
這是實作出 Stack, 前面 mystk.h只是宣告
交通大學資訓工程學系 蔡文能
66
使用 Stack -- File: mymain.cpp
//新寫法
#include "mystk.h"
#include <iostream.h>
# include <iostream>
int main( ) {
using namespace std;
Stack xo, brandy;
xo.push(880);
xo.push(770);
xo.push(53);
while(! xo.isempty( ) ){
cout << " " << xo.pop( );
} cout << endl;
return 0;
}
交通大學資訓工程學系 蔡文能
67
如何執行 前述 Stack 程式 ?
#include "mystk.h"
#include <iostream>
gcc mymain.cpp mystk.cpp
using namespace std;
./a.out
int main( ) {
// OR
Stack xo, brandy;
xo.push(880);
gcc –c mystk.cpp
xo.push(770);
gcc mymain.cpp mystk.o
xo.push(53);
while(! xo.isempty( ) ){ ./a.out
cout << " " << xo.pop( );
} cout << endl; /* new Line*/
53 770 880
return 0;
}
68
交通大學資訓工程學系 蔡文能
Stack (使用) 可全寫在一file, 但??
class Stack {
// private:
long data[99];
/* 直接寫 99 不是好習慣*/
int sptr;
public:
這樣這些會變
Stack( ) { sptr = -1; };
inline function
void push( long xx) { data[ ++sptr ] = xx; }
long pop( ) {return data[sptr--]; }
bool isempty( ) { return sptr == -1;}
};
#include <iostream.h>
int main( ) {
Stack xo, brandy;
壞處:
xo.push(880);
xo.push(770);
若要 reuse Stack 呢?
xo.push(53);
while(! xo.isempty( ) ){
切下來另存檔案?
cout << " " << xo.pop( );
} cout << endl;
不方便! 不符合 OOP 原則
return 0;
69
}
交通大學資訓工程學系 蔡文能
class 內要用 enum 生出常數
/*** g++ thisfile.cpp ; ./a.out ***/
#include<iostream>
using namespace std;
#include<stdio.h>
class Stack {
// private:
public:
enum { size=99 }; /* 正確的好習慣*/
private:
long data[size]; /* 直接寫 99 不是好習慣*/
int sptr; /* stack pointer */
public:
Stack( ) ;
void push( long );
int main( ) {
long pop( );
Stack x;
bool isempty( );
}; /* class Stack */
cout << "Ha ha ha" << endl;
Stack::Stack( ) { }
cout << "stack size = " << Stack::size << endl;
void Stack::push( long y) { }
cout << "Size of x = " << x.size << endl;
long Stack::pop( ) { }
bool Stack::isempty( ) { }
70
}
交通大學資訓工程學系 蔡文能
Stack (其實可用 STL Library 的 stack)
#include <stack>
C++程式庫的stack是 Template class
#include <iostream>
using namespace std; /* where the Library in */
int main( ) {
stack<int> xo; /* 注意用法 stack<int> */
stack<double> brandy; /* 注意用法 */
xo.push(880);
gcc thisfile.cpp
xo.push(770);
./a.out
xo.push(53);
while(! xo.empty( ) ){/* 注意 empty 不是 isempty */
cout << " " << xo.top( ); /* 注意用 top( ) */
xo.pop( );
/* pop is void type */
} cout << endl; /* new Line*/
return 0;
}
53 770 880
交通大學資訓工程學系 蔡文能
71
認真看 class
• C語言的 struct 目的是把相關資料 group 在一起
• class (類別)就是原來的 struct with some regulations
• class is a user-defined data type, 自訂的, 抽象的
• 所以 class 是 Abstract Data Type (ADT)
• ADT 就是把 data 以及對這些 data有關的動作(method, 就是
function)一起封藏(Encapsulate)在一個程式單元(program unit)
之內, 例如 C++ 用 class來封藏
• Class 可用來設計軟體元件(Software Component)
• Class 內的 data member/method member 存取控制:
– private, protected, public (C++ 與 Java 寫法不同)
• Constructor? Destructor? Default Constructor? …
• Java 沒有 Destructor, 但有 finalize 函數
72
交通大學資訓工程學系 蔡文能
問題與思考 (Stack size?)
•Stack 內的 array 一定要固定 99元素嗎?
==> using pointer 就可做出可變大小的array
class Stack {
long * data; int mySize;
Stack(int sz=99);
Default 參數
/* . . . */
};
使用時指定大小:
Stack xo(66);
Stack brandy;
Stack::Stack(int sz) {
sptr = -1; mySize=sz;
data = (long*) malloc(sz * sizeof(long) );
}
交通大學資訓工程學系 蔡文能
73
問題與思考 (Why template?)
•現在用 class 製作軟體零件(元件), 雖可以
有許多個 long 的 Stack
•若要一個 long 的 Stack 以及一個 double
的 Stack 呢?
甚至一個 Student 的 Stack 呢?
• ? Copy 來改並換 class 名稱嗎? NO!
solution ==> using C++ template Class
(樣版類別) (後面講)
74
交通大學資訓工程學系 蔡文能
O O Features
• Encapsulation
• Information Hiding (Data Hiding)
• Inheritance
• Polymorphism
Object Oriented
( 物件導向 )
( 個體導向 )
交通大學資訓工程學系 蔡文能
Object
Based
Software Reuse
75
Stack 應用 again (1/2)
• Infix expression  Postfix expression
• Infix expression: 12+(2*3)/5
• Prefix : +12 / * 2 3 5
Postfix:
12 2 3* 5 + /
76
交通大學資訓工程學系 蔡文能
Stack 應用 again (2/2)
• 使用堆疊把 infix  postfix
– Stack 內放運算符號(operator)和左括號
• 使用堆疊計算 postfix 的答案
– Stack 內放運算元素(operand)或說 value (整
數或實數)
77
交通大學資訓工程學系 蔡文能
問題與思考 (如何做 Queue?
Linked List? )
• 如何表示 Linked List?
• 如何表示 Queue?
– Stack 與 Queue 的應用
• 如何表示Tree?
– 如何儲存 --Binary Tree Representation of
Tree
• Tree 的應用?
– Tree 的 traversal
– Expression tree vs. parsing tree
交通大學資訓工程學系 蔡文能
78
http://www.csie.nctu.edu.tw/~tsaiwn/oop/
Thank You!
謝謝捧場;下次再會
[email protected]
蔡文能
交通大學資訓工程學系 蔡文能
79
Struct – 自訂資料型別(1/5)
#include <stdio.h>
考慮寫個程式處理學生的成
績資料, 如何表示一個學生的
struct Student {
資料? 想一想. . .
long sid;
char name[9]; /*可存四個Big5中文 */
float score[13]; /*每人最多修13 科 */
};
/*注意struct與class之 分號不能省掉*/
int main( ) {
struct Student x; /* C++ 和 C99 不用寫 struct */
x.sid = 123; /* dot notation */
strcpy(x.name, "張大千") ; /*注意字串不能= */
/* 用 loop 把成績讀入 x.score[?] */
80
}
交通大學資訓工程學系 蔡文能
struct --- Structure (2/5)
struct Date {
int day, month, year;
};
void main ( ) {
struct Date birthday = { 14, 2, 1999 };
struct Date today;
today.day = 28;
today.month = 2;
today.year = 2003;
printf("This year is %d", today.year);
…
}
birthday
today
14
birthday.day
2
birthday.month
birthday.year 1999
today
birthday
28
today.day
2
today.month
today.year
2003
81
交通大學資訓工程學系 蔡文能
Structure (3/5)
• Group related fields into a structure
struct date {
int day, month, year;
};
struct date today;
typedef struct date Date;
Date today;
交通大學資訓工程學系 蔡文能
C99 和 C++則只要寫
date today;
82
Structure (4/5)
• 兩種定義一次寫完
typedef struct date {
int day, month, year;
} Date; /* Date為type*/
注意這意思不同!
struct date {
int day, month, year;
} Date; /*Date為變數*/
struct date today;
or
Date today;
83
交通大學資訓工程學系 蔡文能
Structure (5/5)
• Student 是 type
typedef
struct student {
long sid;
char name[9];
float height;
double wet; /*weight*/
} Student;
• What about this?
struct student {
long sid;
char name[9];
float height;
double wet;
} Student, stmp, x[99];
• Student 是 變數
84
交通大學資訓工程學系 蔡文能
Nested Struct, Array of Struct
typedef struct { int d, m, y; } Date;
typedef struct {
char name[49]; /* enough? */
double averageScore;
Date dob; /* date of birth */
} Student; /*一學生 */
typedef struct {
Student stud[66];
int numStud;
} SomeClass; /*一班 */
You can also create an array
as dynamic variable using
malloc( ). The array size
need not be fixed at compile
time.
SomeClass csie1a;
交通大學資訓工程學系 蔡文能
85
typedef struct date {
int d, m, y;
} Date;
Structure as Output Parameter
void scan_date (Date *aday) {
int dd, mm, yy;
scanf("%d %d %d", &dd, &mm, &yy);
(*aday).d = dd;
We need to pass
(*aday).m = mm;
pointer to structure to a
(*aday).y = yy;
function that modifies
}
the structure, similar to
integer.
int main () {
Date today;
scan_date(&today);
print_date(today); ...
}
86
交通大學資訓工程學系 蔡文能
Pointer to Structure(1/2)
void scan_date (Date *aday) {
int dd, mm, yy;
scanf("%d %d %d", &dd, &mm, &yy);
aday->d = dd;
aday->m = mm;
aday->y = yy;
}
typedef struct date {
int d, m, y;
} Date;
交通大學資訓工程學系 蔡文能
A shorthand:
(*aday).d same as aday->d
(*aday).m same as aday->m
87
Pointer to Structure(2/2)
void scan_date (Date *aday) {
scanf("%d %d %d",
&aday->d,
&aday->m,
If we want to set the fields of
&aday->y);
a structure by scanf, we need
}
to pass the address of these
fields.
typedef struct date {
int d, m, y;
} Date;
交通大學資訓工程學系 蔡文能
scan_date(&today);
88
Structure as Parameter
void print_date (Date aday) {
printf("%d/%d/%d",
aday.d, aday.m, aday.y);
} /* call by value */
void scan_date (Date *aday) {
scanf("%d %d %d", &aday->d,
&aday->m, &aday->y);
} /* pass address to pointer */
typedef struct date {
int d, m, y;
} Date;
交通大學資訓工程學系 蔡文能
89
Comparing content of structure
typedef struct { int d, m, y; } Date;
int main ( ) {
Date day1 = { 11, 2, 1999 };
Date day2 = { 1, 12, 1999 };
...
if (day1==day2)  /* wrong */
…
}
Although we can use "=" to
copy structure, we cannot
compare structure by "==".
90
交通大學資訓工程學系 蔡文能
問題與思考 (Data Representation)
• 電腦內如何儲存資料?
– 如何表示文字? ASCII? EBCDIC? …
– 如何表示數值?
• 整數? (char, short, int, long)
long long, boolean ?
• 實數? (float, double)
• 數值的範圍?
• 實數數值的準確度(precision)
• 其它?
long long is introduced in C99
bool is introduced in C++
交通大學資訓工程學系 蔡文能
91
Summary about Data Representation
• 變數(variable)就是佔住記憶體一小塊地方有個名字
• 變數名字要用字母開頭
• 變數的種類(類型):
– 整數: char, (byte), short, int, long, long long (C99才有)
– 實數: float, double, long double
• 數值的絕對值太大無法存入規定格式稱 Overflow
• 數值的絕對值太小無法存入規定格式被電腦當作 0 存起來稱
Underflow , 實數才會! 整數沒有underflow
• Java 語言有 8 種primitive data type
– boolean, byte, char, short, int, long, float, double
• float 的準確度只有二進位24位, 約十進位 7 位強
• double 的準確度只有二進位53位, 約十進位 15 位強
• 自訂型別 ( User Defined Data Type)
92
交通大學資訓工程學系 蔡文能
問題與思考 (ASCII code )
#include<stdio.h>
main( ) {
printf(" %c 的 ASCII code是%d\n", '0', '0');
printf(" %c 的 ASCII code是%d\n", 'A', 'A');
printf(" %c 的 ASCII code是%d\n", 'a', 'a');
}
0 的 ASCII code 是 48
A 的 ASCII code 是 65
a 的 ASCII code 是 97
如果系統使用EBCDIC碼呢?
93
交通大學資訓工程學系 蔡文能
問題與思考 (ASCII code )
#include<stdio.h>
main( ) {
int i, k=0;
for(i=65; i<=122; ++i) {
printf(" %c 的 ASCII code", i);
printf(" 是%d", i);
++k; printf(k%3==0? "\n" : "\t");
} printf("\n" );
}
94
交通大學資訓工程學系 蔡文能
問題與思考 (中文碼?)
#include<stdio.h>
unsigned char x[9] = { 0 };
main( ) {
int m = 0xa4, n=0x6a;
x[0] = m; x[1]=n;
x[2] = 0xae, x[3]=97;
x[4] = 0xa6, x[5]=0x6e;
printf("==%s==\n", x);
}
95
交通大學資訓工程學系 蔡文能
問題與思考 (中文碼?)
先把前面程式存入 testc.c
ccbsd2: tsaiwn> gcc testc.c
ccbsd2: tsaiwn> ./a.out
==大家好==
編
執
譯
行
與
ccbsd2: tsaiwn>
連
結
96
交通大學資訓工程學系 蔡文能
實數與準確度(precision)
#include<stdio.h>
float x, xdelta; int i; /*precision.c */
main( ) { double y;
x = 1234567.2, xdelta = 0.0001;
printf("Before loop, x=%f\n", x);
for(i=1; i<= 8000; i++){
y = x + xdelta;
/******/
if(i == 1) printf("first y = %f\n", y);
x = y;
}
printf("After loop, x=%f\n", x);
}
交通大學資訓工程學系 蔡文能
97
float 實數準確度七位多
ccbsd2:precision/> gcc precision.c
ccbsd2:precision/> ./a.out
Before loop, x=1234567.250000
first y = 1234567.250100
After loop, x=1234567.250000
ccbsd2:precision/>
float 實數佔用 32 bits
98
交通大學資訓工程學系 蔡文能
double 實數準確度
#include<stdio.h>
double x, xdelta; int i; /*precdbl.c */
main( ) { double y;
x = 1234567.2, xdelta = 0.0001;
printf("Before loop, x=%f\n", x);
for(i=1; i<= 8000; i++){
y = x + xdelta;
/******/
if(i == 1) printf("first y = %f\n", y);
x = y;
}
printf("After loop, x=%f\n", x);
}
交通大學資訓工程學系 蔡文能
99
double 實數準確十五位多
ccbsd2:precision/> gcc precdbl.c
ccbsd2:precision/> ./a.out
Before loop, x=1234567.200000
first y = 1234567.200100
After loop, x=1234568.000001
ccbsd2:precision/>
double 實數佔用 64 bits
100
交通大學資訓工程學系 蔡文能
整數 overflow (溢位)
#include<stdio.h>
int main( ) {
short ans = 32765;
int k;
for(k=1; k<= 6; ++k) {
printf ("= %d\n", ans++ );
}
}
= 32765
= 32766
= 32767
= -32768
= -32767
= -32766
物極必反?
101
交通大學資訓工程學系 蔡文能
float實數 overflow (溢位)
/* s eeeeeee efffffff gggggggg hhhhhhhh */
/* +/- 1.fffffffgggggggghhhhhhhh * 2**(eeeeeeee - 127) */
/* eeeeeeee: Exponent base 2 excess 127 */
#include<stdio.h>
#include<math.h>
int main( ) {
float ans = pow(2,125); /* 2 的 125 次方 */
int k;
= 42535295865117307932921825928971026432.000000
for(k=1; k<= 6; ++k) {
= 85070591730234615865843651857942052864.000000
printf("= %f\n", ans );
= 170141183460469231731687303715884105728.000000
ans *= 2.0;
= Inf
}
= Inf
}
Inf = 無窮大
= Inf
102
交通大學資訓工程學系 蔡文能
float實數 underflow(虧失)
/* s eeeeeee efffffff gggggggg hhhhhhhh */
/* +/- 1.fffffffgggggggghhhhhhhh * 2 **(eeeeeeee - 127) */
/* eeeeeeee: Exponent base 2 excess 127 */
#include<stdio.h>
#define DLOOP 146
int main( ) { int k;
float ans = 1.0;
for(k=1; k<= DLOOP; ++k) ans = ans/2.0;
= 1.1210388e-44
/* ans = pow(2, -146);*/
= 5.6051939e-45
for(k=1; k<= 7; ++k){
= 2.8025969e-45
printf("= %12.8g\n", ans );
= 1.4012985e-45
ans /= 2.0;
=
0
} return 0;
=
0
}
=
0
103
交通大學資訓工程學系 蔡文能
for Loop vs. while Loop
for(i=1 ; i<= 9 ; i++)
{
/* Loop body */
}
i=1;
for( ; i<= 9 ; )
{
/* Loop body */
i++;
}
這三個寫法意義
完全一樣
i=1;
while( i<= 9 )
{
/* Loop body */
i++;
}
104
交通大學資訓工程學系 蔡文能
for Loop vs. while Loop
for( ;  ; ) ;
;
while( )
{
;
;
}
交通大學資訓工程學系 蔡文能

== 0

!= 0


105
while Loop (1/3)
拿盤子, 拿飲料, 找好位子;
while(肚子還餓 )
{
All you can eat !
 吃一盤;
喝一杯;
喘一口氣;
}
結帳; 回家;
106
交通大學資訓工程學系 蔡文能
while Loop (2/3)
拿盤子, 拿飲料, 找好位子;
while(肚子還餓 )
{
 吃一盤;
if(有急事 || 很飽了)break;
if(不會渴) continue;
喝一杯;
喘一口氣;
}
結帳; 回家;
All you can eat !
107
交通大學資訓工程學系 蔡文能
while Loop (3/3)
拿盤子, 拿飲料, 找好位子;
while(不夠本 )
{
 吃一盤;
if(有急事 || 很飽了)break;
if(不會渴) continue;
喝一杯;
喘一口氣;
}
結帳; 回家;
108
交通大學資訓工程學系 蔡文能
C++ Template (樣版)
• Templates provide direct support for generic
programming
– The C++ template mechanism allows a type to be a
parameter in the definition of a class or a function
– definer specifies the container class in terms of that
argument
– users specify what the type of contained objects is
• The template implementation is a mechanism that
generates types when needed based on the user’s
specification (compiler 幫忙copy去改 )
• Every major standard library abstraction is
represented as a template
109
交通大學資訓工程學系 蔡文能
C++ Function Template (樣版函數)
template <class T>
void swap( T & x, T & y) {
T temp;
temp=x;
x = y;
y = temp;
}
int main( ) {
int m=38, n=49;
double a=12.34, b=567.135;
swap(a,
b);
如何使用
swap( ) 函數?
swap(m, n);
/** … **/
}
交通大學資訓工程學系 蔡文能
When a template
function is called,
the type of the
function arguments
determine which
version of the
template is used.
That is the template
arguments are
deduced from the
function arguments
110
C++ Class Template
• 如何有多個可處理不同 data type的堆疊?
template <class T>
class Stack {
T data[99];
int sptr;
public :
Stack( );
void push(T x);
T top(void);
void pop(void);
template declaration,
T is type argument
T is uesd exactly like
other type names
Class name is used
exactly like others
But you have to specify
the type in < >
Stack<int> xo;
不該改的不要改, 例
如 int sptr; 當然不改
int empty( ) ;
// . . .
};
template <class T>
Stack<T>::Stack( ) { sptr = -1; }
/* … */
交通大學資訓工程學系
蔡文能
Stack<double> brandy;
Stack<Student> haha;
/* … */
111
review Template(樣板)
• Compiler 在必要時才會把樣版copy 去改並co,mpile
• Template function
– 寫的時候只要在原function前寫個template片語並把原function
的參數與內容稍作修改就完成
– 用的時候沒感覺(transparent), type information 會自動被
compiler 看出來!
– 若一次也沒用則會被compiler丟棄!
• Template class
– 寫的時候要在class前寫個template片語並須把其原各個function
稍作修改
– 用的時候必須指明你要的 type ! 如 Stack<int> xo;
– 若一次也沒用則也會被compiler丟棄!
112
交通大學資訓工程學系 蔡文能