112
交交交交交交交交交交 交交交 1 C++ 交交交交交交交交 Introduction to C++ wi th OOP 交交交 [email protected] [email protected] 交交交交交交交交交交 http://www.csie.nctu.edu.tw/~tsaiwn/cp p/ 01_oop.p pt

C++ 物件導向程式設計 Introduction to C++ with OOP

Embed Size (px)

DESCRIPTION

http://www.csie.nctu.edu.tw/~tsaiwn/cpp/. C++ 物件導向程式設計 Introduction to C++ with OOP. 蔡文能 [email protected] [email protected] 交通大學資訊工程學系. 01_oop.ppt. Agenda. From C to C++ (C++ == a better C + Objec-Oriented support) a. I/O stream, b. pass-by-reference - PowerPoint PPT Presentation

Citation preview

Page 1: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

1

C++ 物件導向程式設計Introduction to C++ with OOP

蔡文能[email protected]@cs.nctu.edu.tw

交通大學資訊工程學系

http://www.csie.nctu.edu.tw/~tsaiwn/cpp/

01_oop.ppt

Page 2: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

2

Agenda 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?

next topic:

Introduction to OOA, OOD, and UML

http://www.csie.nctu.edu.tw/~tsaiwn/cpp/

Page 3: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

3

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, …

Page 4: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

4

C++ Input/Output Stream

• 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;

read(0, …); write(1, …); write(2, …); /* system call */

• In Java, System.out.print("The answer is " + ans + "\n" );

Page 5: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

5

C and C++ I/O comparedC-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.

Page 6: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

6

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;}

int main(){ int mainVal = 9; refFunc(mainVal); cout << "mainVal: " << mainVal << endl; return (0);} mainVal: 50

This assignment changes the memoryassociated with this variable!

Page 7: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

7

參數傳遞 (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 是一個指向整數的指標 !

Page 8: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

8

參數 (parameter) 傳遞 /* 寫一個函數可以將兩整數對調 , wrong version */ #include<stdio.h> void swap( int x, int y) { int temp; temp=x; x = y; y = temp; } int m=38, n=49; int main( ) { swap(m, n); /* 沒有用的 ! 回來後 m, n 不變 */ printf("m=%d, n=%d\n", m, n); }

( 錯 )

因為 C 語言參數是 pass by value

( 錯 )

( 錯 )( 錯 )

Page 9: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

9

參數會被函式改變的傳遞法 /* 寫一個函數可以將兩整數對調 , correct version */ #include<stdio.h> void swap( int * x, int* y) { /* 注意參數寫法 */ int temp; temp = *x; *x = *y; *y = temp; } /* 註 : C++ 則有 pass by reference 寫法 */ int m=38, n=49; int main( ) { swap(&m, &n); /* 注意 &m 和 &n 把 address 傳過去

*/ printf("m=%d, n=%d\n", m, n); }

( 正確 )

參考 K&R 課本 5.2 節

注意不要在 temp 左邊寫星號 , 意思不同

&m, &n : address of m 和 address of n

Call by address to pointer

Page 10: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

10

Call by Reference 參數傳遞 /* 寫一個函數可以將兩整數對調 , in C++ */

#include<stdio.h> void swap( int & x, int & y) { int temp; temp=x; x = y; y = temp; } int m=38, n=49; int main( ) { swap(m, n); /* 注意 ! 看起來好像不會變 */ printf("m=%d, n=%d\n", m, n); }

(C++ 專有 )

C++ 才可以用 pass by Reference

前面所說的 C language 可用之方法仍可以用於 C++.

Page 11: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

11

Function name Overloading

/* 寫個函數可將兩 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++ 專有 )

C++ 允許同名的 function, 但注意參數

Page 12: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

12

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

Page 13: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

13

再談 function name overloadingFunction name overloading 不一定在 class 內 ! 請注意

它與 Object Oriented 並沒有關係 ! function name overloading 是指很多個函數都用同一個名

稱 例如 : int m=2, n=3; double x=3.8, y=4.9; swap(m, n); swap(x, y); 顯然以上兩個 swap 應該是不同函數 , 這是由它們的參數不同得知的 !

這在 compile time 就可以決定是用哪一個 swap, 此稱之為 static binding ( 靜態繫結 )! 如何做 ? (next slide)

? 何謂 dynamic binding? (next slide)

C++ 允許同名的 function, 但注意參數

Page 14: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

14

C++ How to …overloading/polymorphism

C++ 到底是用了什麼技術辦到 function name overloading ? 事實上只是用了一個超級簡單的 idea:– C++ 只是把參數的型別納入函數名稱中而已 , Comp

iler 會偷換 function name, 參數的 type 也變成 function_name 的一部份 : ( static binding)

例如 : void swap(int&, int&); 會被譯為 ( 可能 !): __swap_F2RiRi

如何達成 polymorphism ?透過 virtual function dynamic binding p-> draw( ); 譯成去執行 p 指過去之物件內有

個指標指過去的函數表中 draw 的項目位置指過去的那個函數 ! ( 相關指標在 new 出物件時填入 )

Page 15: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

15

Tips about Dynamic binding

Dynamic binding( 動態繫結 ) 是指在 執行階段(run time) 才確定 !

動態繫結是一種被 Compiler 使用的技術 , 它也不是 OO 才有的 , C 語言的 Auto 變數 ( 函數中沒有宣告 static 的 Local 變數 ) 就是使用Dynamic binding; 在執行期 (Run time) 時才安排於堆疊 (Stack) 中 !

Static binding? vs. Dynamic binding?

Page 16: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

16

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 o

perator (+)

Page 17: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

17

Operator overloading (2/4)

• You can NOT invent operator– No new operators can be created, use only existing ope

rators• 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

Page 18: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

18

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 non-member function

– A non-member operator function must be a friend if private or protected members of that class are accessed directly

Page 19: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

19

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

Page 20: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

20

Operators in C / C++ / Java(1/3):

Operator C C++ Java

Scope res. ::

Member selection, subscripting, function call, sizeof

. -> [] () . -> [] () sizeof

n/a n/a [] () n/a

Unary ops, address, dereference, cast, allocate, deallocate

- ! ++ -- & * () n/a n/a

- ! ++ -- & * () new delete

- ! ++ -- n/a n/a () n/a n/a

Multiply, divide, mod * / % * / % * / %

Add, subtract + - + - + -

Shift << >> << >> << >>

Page 21: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

21

Operators in C / C++ / Java (2/3):

Operator C C++ Java

relational < <= > >= < <= > >= < <= > >=

equality == != == != == !=

bitwise AND & & &

bitwise XOR ^ ^ ^

bitwise OR | | |

logical AND && && &&

logical OR || || ||

Page 22: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

22

Operators in C / C++ / Java (3/3):

Operator C C++ Java

conditional ? : ? : ? :

assignment = *= /= %= += -= <<= >>= &= != ^=

= *= /= %= += -= <<= >>= &= != ^=

= *= /= %= += -= <<= >>= &= != ^=

exception throw

sequencing , , ,

Page 23: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

23

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; // …// then:

y += z; // equivalent to y.operator+=( z ); //operator+= is a member

表示不會改 member data,

此例顯然不該寫這個 const, Why?

Page 24: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

24

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+= 應寫成自己人比較好

Page 25: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

25

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?

Page 26: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

26

Default parametervoid setNum(int x = 3388);void setNum(int x) { cout << "You gave me " << x << endl; // …}

setNum(123);setNum( ); /* compiler 會自動填入 3388 */setNum(456);

Page 27: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

27

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 func

tion. 這是要求 Compiler 採用類似 Macro ( 巨集 ) 展開方式來翻譯該函數呼叫 !

所以通常機器碼較佔空間 , 但執行起來比較快 ( 用空間換時間 ); 但是它仍然具有 function 的效果 ! 注意 : 含有某些 statements 的 functions 無法成為 inline, compiler 會把關 !

Page 28: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

28

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)

Page 29: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

29

再 談 變數 Variable 變 變 變• 變數當然會變才叫變數 – 廢話 !

– 變數命名規則與慣例 ? averageScore, n, x

• 變數放在電腦的記憶體 – 何處 ?– 與程式一起 , 與程式分離 ? – 由 Linker 負責– 堆疊區 (STACK) ? 嘿洗蝦密碗糕啊 ?

• 變數的能見範圍 (Scope)? 或說有效範圍– 函數 ( 函式 ) 內的變數 :Local variable 局部 ( 區域 ) 變數– 函數外的變數 : Global variable整體變數

• 變數何時生出 ? 何時死掉 ? 生命期 (Life time) ?

Page 30: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

30

變數分類• 依能見範圍 (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 ( 堆積 )

Page 31: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

31

變數 (Variable) 的 Scope, Life time

• 變數的能見範圍 (Scope, 或說有效範圍 )– 函數 ( 函式 ) 內的變數 :Local variable 局部 ( 區域 )

變數 : 只有在函數內有效– 函數外的變數 : Global variable (整體變數 )– Global variable : 宣告之後就一直有效

• 變數生命期 (Life time) ? – 靜態變數從程式開始 Run 就“出生”– Auto 變數在進入函數時生出 , 離開函數時死掉 ( 把

記憶體還給系統 )– 沒有宣告 static 的 :Local 變數就是 Auto 變數

Page 32: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

32

Global 變數 vs. Local 變數 #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 */ }

(1/2)

Page 33: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

33

Global 變數 vs. Local 變數 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 ; /* 不寫也可以 */

}

(2/2)

pass by value 就是 call by value

講法不同而已

Page 34: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

34

Static Local 變數 #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; 不同 !

(1/2)

Page 35: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

35

Static Local 變數 int fa( ) {

int x = 1;

return x++; /* 先取其值 , 再做 ++ */

}

int fb( ) {

static // 把 static 寫在下列左方也一樣 int x = 1; // 注意 static int x = 1;

return x++;

}

(2/2)

Page 36: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

36

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( ) … 也可以寫在另一個檔案內

Page 37: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

37

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 的人高興

Page 38: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

38

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 中 的參數 , 那是叫用函數那個程式的責任 ! ( 與其它語言不同 )

Page 39: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

39

Auto 變數佔用 STACK 區 memory

•Auto 變數就是沒寫 static 的 Local 變數

CPUIP

SP

Instruction Pointer

Stack Pointer

系統區

系統區

程式 + 靜態 data

HEAP 堆積malloc( ), new( )

STACK( 參數與 Auto 變數 )

Heap 由上往下長

Stack 由下往上長

address 0

Page 40: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

40

Static 變數 ?•Global 變數都是 static 的 變數•Local 變數就是寫在函數內的變數

– 有補 static 修飾詞則為 static 變數 ( 靜態變數 )

– 沒有補 static 修飾詞則為 Auto 變數 ( 自動變數 )

•static 的 變數在程式開始 RUN 之前就存在 , 且已經設好初值 , 程式結束後才會還掉所佔記憶體 ( 生命期 )

•寫了 extern 表示只是 宣告 (declare), 不是定義 (define)•Local 變數就只能在該函數 (function) 內存取 (access)

•Global 變數則只要看得見它的任一函數都能存取它– 宣告之後就看得見 , 沒宣告就定義 則看作 同時宣告了

•注意 main( ) 也是函數 , 沒有特別偉大 ! 應寫成 int function.

Page 41: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

41

Global, Static Local, Auto 變數 #include <stdio.h>

extern int x; /* 只有宣告 , 還不知道位置在何處 ?*/

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 ( ) { /*…* }

寫了 extern 表示只是 宣告 , 不是定義 (define)

Page 42: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

42

Static Global 變數 #include <stdio.h>

#define BUFSIZE 100

static char buf[BUFSIZE];

static int bufp = 0;

int getch( ) {

/* . . . */

}

void ungetch(int c) {

/* . . . */

}

Information Hiding?

也參考 stack 的 push 和 pop 寫在同一獨立 file 中 , push 和 pop共享 data

Functions in another file can NOT see these static variable

Page 43: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

43

再談 Static Global 變數 #include <stdio.h>

#define RAND_MAX 65535

static unsigned long seed=0; /* global */

int rand( ) {

seed = seed * 1103515245 + 12345;

return seed % (RAND_MAX+1);

}

void srand(int newseed) {

seed = newseed;

}

程式庫中的 Pseudo Random Number Generator (PRNG)

Information Hiding?

只有 rand 和 srand 看得見 seed

Page 44: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

44

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;

/* . . . */

p = &yy; /* this is wrong */

} 參考 K&R課本 4.7節

拜託 Compiler儘可能安排在 CPU

內的暫存器

Page 45: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

45

volatile 變數 #include <stdio.h>

volatile int haha ; /* tell 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節

警告 Compiler 這變數可能會被別

的程式改變

Page 46: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

46

• 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.

ADT --- Data Abstraction

Page 47: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

47

ADT in C_plus_plusclass / struct can be used as the encapsulation

device. ( 只有一開始 default access屬性不同 )All of the class instances of a class share a sin

gle copy of the member functions.Each instance of a class has its own copy of th

e 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

Page 48: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

48

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 r

elated data in struct ( class )– 所以 C++ 的 class 就是 C 的 struct 加上

一些規定– Java 把 struct 拿掉了 ! 且 union 也沒了 !

• class 有何用 ? (後面講 )

Page 49: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

49

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) 在一個程式單元方便使用

Page 50: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

50

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

Page 51: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

51

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; return 0; }

How?

如何製作 Stack?

Page 52: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

52

Take a Break (12 min.)Take a Break (12 min.)

不要跑掉[email protected]

蔡文能

Why using struct ?

Page 53: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

53

問題與思考 (如何自定資料結構 ?) Why using struct ?• 只能用 char, int, float, double 等這些 data t

ype 嗎 ?• User defined data type?• 考慮寫程式處理全班成績資料 , 包括加總平均並排序 (Sort) 然後印出一份照名次排序的全部資料以及一份照學號排序的全班資料– 如何做 Sort ( 排序 ) ? – Sort 時兩學生資料要對調 , 要如何對調 ?– 有很多 array ? 存學號的 array, 存姓名的 array? 存成績的 array? … 萬一忘了一個 array?

Bubble sort, Insertion sort, Selection sort

Page 54: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

54

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

Page 55: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

55

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 用大寫字母開頭 !

Page 56: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

56

What is Object? Class? (1/2)

• object 就是“東西” , 就是以前的“變數”

• class 就是“類別” , 某種東西的型別

int m, n; /* int 是整數類別 */

/* m, n 都是變數 */

Student x, y; /* Student 是我們自訂類別 */

/* x, y 都是 object */

Page 57: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

57

What is Object? Class? (2/2)

• object is an instance of some class

• 文法上 , C++ 的 class 就是以前的 structclass Student { public:

/* … 與寫 struct 同 */

};

struct Node { private:

/* … 與寫 class 同 */

};

Page 58: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

58

Class 與 struct 文法上 ?

class Student { // private:

long sid;

char name[9];

};

Student x, y[99], tempstu;

不可以使用 x.sid 等等Why ??

Information hiding

struct Student{

long sid;

char name[9];

};

Student x, y[99], tempstu;

可以使用 x.sid

y[3].sid = tempstu.sid;

Page 59: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

59

用 array 來做 STACK (1/2)•

sptrStack Pointer

int sptr;

01

-1

int x[99];

void push (int y) { ++sptr; x[sptr] = y;}

int ans = pop( );

Initialization:

sptr = -1; /*empty*/

需要一個 array 和一個整數

push (456) ;

push (3388) ;

4563388

int pop ( ) { int tmp=x[sptr]; --sptr; return tmp;}

98

Page 60: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

60

用 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( ) */

Page 61: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

61

使用 STACK extern void push(int); /* 宣告 */ extern int pop( ); #include <stdio.h> int main( ) { push(543); push(881); printf("%d\n", pop( ) ); } /* 可以用 ! 但若要兩個 Stack 呢 ? */

Page 62: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

62

More about STACK (1/3)/* 若要兩個 Stack 呢 ? */

解法之一 ==> 使用兩個 array, 並把 array 當參數

push(ary2, x); ans = top(ary2);

但是這樣該些 array 必須 開放讓使用者知道 要讓宣告 extern 就看得到 , 不可再用 static Global

違反不必讓使用者知道 push 到哪去的 Information Hiding 原則 !

( 或是該些 array 要定義在使用者程式裡面 , 更不好 !)

Page 63: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

63

More about STACK (2/3)/* 若要兩個 Stack 呢 ? */

解法之二 (better, but NOT good enough!)==> 整個檔案複製到另一個 file, 並把 各相關函數名稱都改掉 , 例如 push2, pop2, …==> array 與變數名稱都不用改 ! Why?

( 因為 static Global 使其它 file 中 function 看不見 )但是這樣 也不是很方便 , 函數名稱一大堆

若要三個 Stack 呢 ? 四個呢 ? …

( 不過這比前面使用不同 array 的方法好 !)

Page 64: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

64

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( ) );

Page 65: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

65

Stack -- class example ( 1/2) mystk.h

class Stack { // private:

long data[99]; /* 直接寫 99 不是好習慣*/

int sptr;

public:

Stack( ) ; /* constructor */

void push( long );

long pop( );

bool isempty( );

}; /* class Stack */

bool 要新版的 C++ 才有 , 如果不能用就改用 int

標準程式庫的堆疊是 stack 注意是小寫 ! 且其 pop( ) 是 void

標準程式庫是 empty

Page 66: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

66

Stack -- class example (2/2) mystk.cpp

#include "mystk.h"

#include <iostream.h>

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 只是宣

Initialization 工作 要寫在特殊函數

Page 67: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

67

使用 Stack -- File: mymain.cpp #include "mystk.h"

#include <iostream.h>

int main( ) {

Stack xo, brandy;

xo.push(880);

xo.push(770);

xo.push(53);

while(! xo.isempty( ) ){

cout << " " << xo.pop( );

} cout << endl;

return 0;

}

//新寫法

# include <iostream>

using namespace std;

Page 68: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

68

如何執行 前述 Stack 程式 ? #include "mystk.h" #include <iostream> using namespace std; int main( ) { Stack xo, brandy; xo.push(880); xo.push(770); xo.push(53); while(! xo.isempty( ) ){ cout << " " << xo.pop( ); } cout << endl; /* new Line*/ return 0; }

53 770 880

gcc mymain.cpp mystk.cpp

./a.out

gcc –c mystk.cpp

gcc mymain.cpp mystk.o

./a.out

// OR

Page 69: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

69

Stack ( 使用 ) 可全寫在一 file, 但 ??class Stack { // private: long data[99]; /* 直接寫 99 不是好習慣 */ int sptr; public:

Stack( ) { sptr = -1; };

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); xo.push(53); while(! xo.isempty( ) ){ cout << " " << xo.pop( ); } cout << endl; return 0; }

壞處 :

若要 reuse Stack 呢 ?

切下來另存檔案 ?

不方便 ! 不符合 OOP 原則

這樣這些會變 inline function

這樣這些會變 inline function

Page 70: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

70

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 ); long pop( ); bool isempty( );}; /* class Stack */Stack::Stack( ) { }void Stack::push( long y) { }long Stack::pop( ) { }bool Stack::isempty( ) { }

int main( ) {

Stack x;

cout << "Ha ha ha" << endl;

cout << "stack size = " << Stack::size << endl;

cout << "Size of x = " << x.size << endl;

}

Page 71: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

71

Stack ( 其實可用 STL Library 的 stack)

#include <stack> #include <iostream> using namespace std; /* where the Library in */ int main( ) { stack<int> xo; /* 注意用法 stack<int> */ stack<double> brandy; /* 注意用法 */ xo.push(880); xo.push(770); 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

gcc thisfile.cpp

./a.out

C++ 程式庫的 stack 是 Template class

Page 72: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

72

認真看 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 函數

Page 73: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

73

問題與思考 (Stack size?)• Stack 內的 array 一定要固定 99 元素嗎 ?

==> using pointer 就可做出可變大小的 array class Stack { long * data; int mySize; Stack(int sz=99); /* . . . */

} ;

Stack::Stack(int sz) { sptr = -1; mySize=sz; data = (long*) malloc(sz * sizeof(long) );}

使用時指定大小 :

Stack xo(66);

Stack brandy;

Default 參數

Page 74: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

74

問題與思考 (Why template?)• 現在用 class 製作軟體零件 (元件 ), 雖可以有許多個 long 的 Stack

• 若要一個 long 的 Stack 以及一個 double 的 Stack 呢 ? 甚至一個 Student 的 Stack 呢 ?

• ? Copy 來改並換 class 名稱嗎 ? NO!

solution ==> using C++ template Class

( 樣版類別 ) ( 後面講 )

Page 75: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

75

O O Features

• Encapsulation• Information Hiding (Data Hiding)

• Inheritance• Polymorphism

Object Based

Object Oriented ( 物件導向 ) ( 個體導向 )

Software Reuse

Page 76: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

76

Stack 應用 again (1/2)

• Infix expression Postfix expression

• Infix expression: 12+(2*3)/5

• Prefix : +12 / * 2 3 5

* + /Postfix: 12 2 3 5

Page 77: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

77

Stack 應用 again (2/2)

• 使用堆疊把 infix postfix– Stack 內放運算符號 (operator)和左括號

• 使用堆疊計算 postfix 的答案– Stack 內放運算元素 (operand) 或說 value

(整數或實數 )

Page 78: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

78

問題與思考 (如何做 Queue? Linked List? )

• 如何表示 Linked List?• 如何表示 Queue?

– Stack 與 Queue 的應用• 如何表示 Tree?

– 如何儲存 --- Binary Tree Representation of Tree

• Tree 的應用 ?– Tree 的 traversal– Expression tree vs. parsing tree

Page 79: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

79

Thank You!Thank You!謝謝捧場 ; 明天再會

[email protected]

蔡文能

http://www.csie.nctu.edu.tw/~tsaiwn/oop/

Page 80: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

80

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[?] */ }

考慮寫個程式處理學生的成績資料 , 如何表示一個學生的資料 ? 想一想 . . .

Page 81: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

81

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); …}

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); …}

today

28

2

2003

today.day

today.monthtoday.year

birthday

14

2

1999

birthday.day

birthday.month

birthday.year

birthday

today

Page 82: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

82

Structure (3/5)

• Group related fields into a structure

typedef struct date Date;typedef struct date Date;

struct date { int day, month, year;};

struct date { int day, month, year;};

struct date today;struct date today;

Date today;Date today;

C99 和 C++ 則只要寫 date today;

C99 和 C++ 則只要寫 date today;

Page 83: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

83

Structure (4/5)

• 兩種定義一次寫完

typedef struct date { int day, month, year;} Date; /* Date 為 type*/

typedef struct date { int day, month, year;} Date; /* Date 為 type*/

struct date today; orDate today;

struct date today; orDate today;

注意這意思不同 !struct date { int day, month, year;} Date; /*Date 為變數 */

注意這意思不同 !struct date { int day, month, year;} Date; /*Date 為變數 */

Page 84: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

84

Structure (5/5)

• Student 是 type

typedef struct student { long sid; char name[9]; float height; double wet; /*weight*/} Student;

typedef struct student { long sid; char name[9]; float height; double wet; /*weight*/} Student;

struct student { long sid; char name[9]; float height; double wet; } Student, stmp, x[99];

struct student { long sid; char name[9]; float height; double wet; } Student, stmp, x[99];

• What about this?

• Student 是 變數

Page 85: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

85

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; /* 一班 */

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; /* 一班 */

SomeClass csie1a;SomeClass csie1a;

You can also create an array as dynamic variable using malloc( ). The array size need not be fixed at compile time.

You can also create an array as dynamic variable using malloc( ). The array size need not be fixed at compile time.

Page 86: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

86

Structure as Output Parameter

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;}int main () { Date today; scan_date(&today); print_date(today); ...}

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;}int main () { Date today; scan_date(&today); print_date(today); ...}

We need to pass pointer to structure to a function that modifies the structure, similar to integer.

We need to pass pointer to structure to a function that modifies the structure, similar to integer.

typedef struct date { int d, m, y;} Date;

typedef struct date { int d, m, y;} Date;

Page 87: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

87

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;}

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;}

A shorthand:(*aday).d same as aday->d(*aday).m same as aday->m

A shorthand:(*aday).d same as aday->d(*aday).m same as aday->m

typedef struct date { int d, m, y;} Date;

typedef struct date { int d, m, y;} Date;

Page 88: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

88

Pointer to Structure(2/2)

void scan_date (Date *aday) { scanf("%d %d %d", &aday->d, &aday->m, &aday->y);}

void scan_date (Date *aday) { scanf("%d %d %d", &aday->d, &aday->m, &aday->y);}

If we want to set the fields of a structure by scanf, we need to pass the address of these fields.

scan_date(&today);

If we want to set the fields of a structure by scanf, we need to pass the address of these fields.

scan_date(&today);typedef struct date { int d, m, y;} Date;

typedef struct date { int d, m, y;} Date;

Page 89: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

89

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 */

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;

typedef struct date { int d, m, y;} Date;

Page 90: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

90

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 */ …}

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 "==".

Although we can use "=" to copy structure, we cannot compare structure by "==".

Page 91: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

91

• 電腦內如何儲存資料 ?– 如何表示文字 ? ASCII? EBCDIC? …– 如何表示數值 ?

•整數 ? (char, short, int, long) long long, boolean ?• 實數 ? (float, double)• 數值的範圍 ?• 實數數值的準確度 (precision)•其它 ?

問題與思考 (Data Representation)

long long is introduced in C99

bool is introduced in C++

Page 92: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

92

Summary about Data Representation

• 變數 (variable) 就是佔住記憶體一小塊地方有個名字• 變數名字要用字母開頭• 變數的種類 ( 類型 ):

– 整數 : char, (byte), short, int, long, long long (C99 才有 )– 實數 : float, double, long double

• 數值的絕對值太大無法存入規定格式稱 Overflow• 數值的絕對值太小無法存入規定格式被電腦當作 0 存起來稱 Un

derflow , 實數才會 ! 整數沒有 underflow

• Java 語言有 8 種 primitive data type– boolean, byte, char, short, int, long, float, double

• float 的準確度只有二進位 24 位 , 約十進位 7 位強• double 的準確度只有二進位 53 位 , 約十進位 15 位強• 自訂型別 ( User Defined Data Type)

Page 93: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

93

問題與思考 (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 是 48A 的 ASCII code 是 65a 的 ASCII code 是 97

如果系統使用 EBCDIC碼呢 ?

Page 94: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

94

問題與思考 (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" );}

Page 95: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

95

問題與思考 (中文碼 ?)#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);}

Page 96: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

96

問題與思考 (中文碼 ?)

ccbsd2: tsaiwn> gcc testc.cccbsd2: tsaiwn> ./a.out==大家好 ==

ccbsd2: tsaiwn>

先把前面程式存入 testc.c

Page 97: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

97

實數與準確度 (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);}

Page 98: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

98

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

Page 99: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

99

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);}

Page 100: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

100

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

Page 101: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

101

整數 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

物極必反 ?

Page 102: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

102

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; for(k=1; k<= 6; ++k) { printf("= %f\n", ans ); ans *= 2.0; }} Inf = 無窮大

= 42535295865117307932921825928971026432.000000

= 85070591730234615865843651857942052864.000000

= 170141183460469231731687303715884105728.000000

= Inf

= Inf

= Inf

Page 103: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

103

float 實數 underflow(虧失 )/* s eeeeeee efffffff gggggggg hhhhhhhh *//* +/- 1.fffffffgggggggghhhhhhhh * 2 **(eeeeeeee - 127) *//* eeeeeeee: Exponent base 2 excess 127 */#include<stdio.h>#define DLOOP 146int main( ) { int k; float ans = 1.0; for(k=1; k<= DLOOP; ++k) ans = ans/2.0; /* ans = pow(2, -146);*/ for(k=1; k<= 7; ++k){ printf("= %12.8g\n", ans ); ans /= 2.0; } return 0;}

= 1.1210388e-44

= 5.6051939e-45

= 2.8025969e-45

= 1.4012985e-45

= 0

= 0

= 0

Page 104: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

104

for Loop vs. while Loopfor(i=1 ; i<= 9 ; i++){ /* Loop body */}

i=1;for( ; i<= 9 ; ){ /* Loop body */ i++;}

i=1;while( i<= 9 ){ /* Loop body */ i++;}

這三個寫法意義這三個寫法意義完全一樣完全一樣

Page 105: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

105

for Loop vs. while Loop

for( ; ; ) ;

;while( ){ ; ;}

== 0

!= 0

Page 106: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

106

while Loop (1/3)

拿盤子 , 拿飲料 , 找好位子 ;while(肚子還餓 ){ 吃一盤 ; 喝一杯 ; 喘一口氣 ;}結帳 ; 回家 ;

All you can eat !

Page 107: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

107

while Loop (2/3)

拿盤子 , 拿飲料 , 找好位子 ;while(肚子還餓 ){ 吃一盤 ; if(有急事 || 很飽了 )break; if(不會渴 ) continue; 喝一杯 ; 喘一口氣 ;}結帳 ; 回家 ;

All you can eat !

Page 108: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

108

while Loop (3/3)

拿盤子 , 拿飲料 , 找好位子 ;while( 不夠本 ){ 吃一盤 ; if(有急事 || 很飽了 )break; if(不會渴 ) continue; 喝一杯 ; 喘一口氣 ;}結帳 ; 回家 ;

Page 109: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

109

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

Page 110: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

110

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(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

如何使用 swap( ) 函數 ?

Page 111: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

111

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); int empty( ) ; // . . .};template <class T>Stack<T>::Stack( ) { sptr = -1; }/* … */

template declaration, T is type argument

T is uesd exactly like other type names

Stack<int> xo;

Stack<double> brandy;

Stack<Student> haha;

/* … */

Class name is usedexactly like othersBut you have to specify the type in < >

不該改的不要改 , 例如 int sptr; 當然不改

Page 112: C++  物件導向程式設計 Introduction to C++ with OOP

交通大學資訓工程學系 蔡文能

112

review Template( 樣板 )

• Compiler 在必要時才會把樣版 copy 去改並 co,mpile• Template function

– 寫的時候只要在原 function 前寫個 template片語並把原 function 的參數與內容稍作修改就完成

– 用的時候沒感覺 (transparent), type information 會自動被 compiler 看出來 !

– 若一次也沒用則會被 compiler丟棄 !

• Template class– 寫的時候要在 class 前寫個 template片語並須把其原各個 functi

on稍作修改– 用的時候必須指明你要的 type ! 如 Stack<int> xo;– 若一次也沒用則也會被 compiler丟棄 !