Speaker: Liu Yu-Jiun Date: 2009/5/6 Recitation Course 0506 Speaker: Liu Yu-Jiun Date: 2009/5/6
About strtok char *strtok ( char *s1, const char *s2); #include <iostream> using namespace std; int main(){ char s[] = "This is a sentence with 7 tokens"; char *tokenPtr; tokenPtr = strtok(s, "T "); while(tokenPtr != NULL){ cout << tokenPtr << endl; tokenPtr = strtok(NULL, " "); } return 0; Result: his is a sentence with 7 tokens You can put any delimiting character in this string.
About strtok If the delimiting character is the beginning of the string, the return value will be the remain part.
reference: C++ How to Program 6e Sizeof Operator Returns size of operand in bytes at compiler-time Can be used with Variable names Type names (need parentheses) Constant values For arrays, sizeof returns ( size of 1 element ) * ( number of elements ) If sizeof( int ) returns 4 then int myArray[ 10 ]; cout << sizeof( myArray ); will print 40 For double realArray[ 22 ]; Use sizeof realArray / sizeof( double ) to calculate the number of elements in realArray Return type is size_t 是運算子不是函式 會影響編譯時間,不會影響執行時間 reference: C++ How to Program 6e
reference: C++ How to Program 6e Pointer Arithmetic Increment/decrement pointer (++ or --) Add/subtract an integer to/from a pointer (+ or +=, - or -=) Pointer arithmetic is meaningless unless performed on a pointer to an array. int a[] = {10, 20, 30, 40, 50, 60}; int *ptr = a; int *ptr1 = ptr; ptr1 = ptr1 + 3; cout << ptr1 - ptr << endl; cout << *ptr1 << endl; a 10 20 30 40 50 60 ptr ptr1 指標之間的加減其實沒有什麼太大的意義,因為存放的都是位址 3 40 reference: C++ How to Program 6e
reference: C++ How to Program 6e Portability Tip 8.3 Most computers today have two-byte or four-byte integers. Some of the newer machines use eight-byte integers. Because the results of pointer arithmetic depend on the size of the objects a pointer points to, pointer arithmetic is machine dependent. 每台電腦用來表示整數的位元組大小不相同,根據每台電腦不同,sizeof出來的結果就會不同 因此,指標算術的結果是與機器相關的 reference: C++ How to Program 6e 6
Example #include <iostream> using namespace std; int main(){ int v[5] = {0}; int *vPtr = v; for (int i = 0 ; i < 5 ; i++){ cout << (vPtr + i) << endl; // cout << vPtr++ << endl; } system("PAUSE"); return 0; 0x23ff50 0x23ff54 0x23ff58 0x23ff5c 0x23ff60
Relationship Between Pointers and Arrays Array name is like constant pointer Pointers can do array subscripting operations Accessing array elements with pointers Assume declarations: int b[ 5 ]; int *bPtr; bPtr = b; Element b[ n ] can be accessed by *( bPtr + n ) Called pointer/offset notation Addresses &b[ 3 ] is same as bPtr + 3 Array name can be treated as pointer b[ 3 ] is same as *( b + 3 ) Pointers can be subscripted (pointer/subscript notation) bPtr[ 3 ] is same as b[ 3 ] 1. Offset指出應參照哪個陣列元素,其值等於陣列的附標。 reference: C++ How to Program 6e
Four ways for referring the array elements int b[] = {10, 20, 30, 40}; int *bPtr = b; for (int i = 0; i < 4; i++){ cout << b[i] << endl; // cout << *(b+i) << endl; // cout << bPtr[i] << endl; // cout << *(bPtr+i) << endl; } reference: C++ How to Program 6e
Four ways for referring the 2D array elements b int b[4][5] = {10, 20, 30, 40, 50, 60, 70, 80}; int (*bPtr)[5] = b; for (int i = 0; i < 4; i++){ for (int j = 0; j < 5; j++){ cout << b[i][j] << endl; // cout << *(*(b + i) + j) << endl; // cout << bPtr[i][j] << endl; // cout << *(*(bPtr + i) + j) << endl; } 10 20 30 40 50 60 70 80 int *bPtr[5] = b; //compile error *bPtr
reference: C++ How to Program 6e Pointer Assignment Pointer can be assigned to another pointer if both are of same type. If not the same type, cast operator must be used. Exception Pointer to void (type void *) Generic pointer, represents any type No casting needed to convert pointer to void * Casting is needed to convert void * to any other type void pointers cannot be dereferenced Pointer可以被assign給另一個指標,只要它們的指到的型態是一樣的。 換句話說,想要把指向type A的指標assign給指向type B的指標就一定要經過轉換。 任何資料型態的指標都可以先轉換成void型態的指標,再成功轉換回原指標的型態。 如果在函式使用void指標的參數,可以使用任何資料型態的指標作為傳遞的參數。 Void型態的指標除了拿來比較之外,不能做其他的運算。 Void指標可以指向任何型態的變數,但是void指標只有記錄所指資料的起始位址,而無紀錄資料的型態(記憶體大小/如何解讀), 所以對其位址取值時需強制轉換其型別。 reference: C++ How to Program 6e
Classes: A Deeper Look, Part 1 Chapter 9 Classes: A Deeper Look, Part 1
reference: C++ How to Program 6e Introduction Preprocessor wrapper Three types of “handles” on an object Name of an object (.) Reference to an object (.) Pointer to an object () Class functions Predicate functions (access functions) Utility functions (helper functions) Passing arguments to constructors Using default arguments in a constructor Destructor Performs “termination housekeeping” 如何使用前置處理包裝,避免多次含括同一標頭檔 三種用來存取類別public成員的方式(物件名稱、透過物件的參照、指向物件的指標) 類別中兩種函式的類型(判斷函式與工具函式),判斷函式又稱為存取函式(set, get),可以讀取或顯示成員資料,也可以測試條件的真偽;工具函式又稱為助手函式,這種函式是類別的private成員函式,用來幫助類別的public函式完成工作,使用類別的外部程式無法直接呼叫它們。 另一個例子,示範如何將引數傳入建構子,以及如何在建構子中使用預設引數。 討論解構子,用來在物件被摧毀之前進行的資源回收工作。 reference: C++ How to Program 6e
Preprocessor wrappers Prevents code from being included more than once #ifndef – “if not defined” Skip this code if it has been included already #define Define a name so this code will not be included again #endif If the header has been included previously Name is defined already and the header file is not included again Prevents multiple-definition errors Example #ifndef TIME_H #define TIME_H … // code #endif 在標頭檔中使用”前置處理包裝(preprocessor wrapper)”,避免在原始當中重覆含括同一個標頭檔。 類別只能定義一次,所以這個技巧可以避免發生重覆定義的錯誤。 reference: C++ How to Program 6e
Preprocessor directive #ifndef determines whether a name is defined Preprocessor directive #define defines a name (e.g., TIME_H) TIME_H可以改變,只是通常取的名稱會跟檔名相似,全部改大寫,”.”換成”_”。 一個建構子,三個public函式,三個private members。 Preprocessor directive #endif marks the end of the code that should not be included multiple times reference: C++ How to Program 6e
reference: C++ How to Program 6e Ensure that hour, minute and second values remain valid 時間建構子把所有資料成員的初始值都設為0 reference: C++ How to Program 6e
reference: C++ How to Program 6e 當輸出的東西比輸出欄位少的時候,就使用setfill指定的字元填滿它,預設的情況下,填充字元會出現在數字的左邊。 setfill有黏著性設定(sticky setting),一出現setfill之後,其後的輸出欄位都會使用同一個填充字元來填充。 setw只會對下一個欄位作用,所以setw為non-sticky setting。 reference: C++ How to Program 6e
reference: C++ How to Program 6e
reference: C++ How to Program 6e
Time Class Case Study (Cont.) Member function declared in a class definition but defined outside that class definition Still within the class’s scope Known only to other members of the class unless referred to via Object of the class Reference to an object of the class Pointer to an object of the class Binary scope resolution operator Member function defined in the body of a class definition C++ compiler attempts to inline calls to the member function 成員函式若在類別定義的主體中定義,C++編譯器會試著把它變成行內函式(inline)。定義在類別定義外部的成員函式,則可透過關鍵字inline宣告為行內函式。 把小型的成員函式定義放在類別定義之中,可以讓此函式成為行內函式,可以提高程式效能,可是由軟體工程的角度來看並不好(因為會讓其他人看到這個成員函式的實作) reference: C++ How to Program 6e
reference: C++ How to Program 6e Time Class Case Study Using class Time Once class Time has been defined, it can be used in declarations Time sunset; Time arrayOfTimes[ 5 ]; Time &dinnerTime = sunset; Time *timePtr = &dinnerTime; reference: C++ How to Program 6e
reference: C++ How to Program 6e #include <iostream> #include "Time.h" using namespace std; int main(){ Time wakeup, breakfast, lunch, sunset, gobed; Time &dinnerTime = sunset; Time *timePtr = &dinnerTime; wakeup.setTime(8, 30, 0); breakfast.setTime(9, 0, 0); lunch.setTime(11, 55, 15); gobed.setTime(23, 58, 40); sunset.setTime(18, 27, 6); Time arrayOfTimes[5] = {wakeup, breakfast, lunch, sunset, gobed}; cout << "Schedule: " << endl; for (int i = 0 ; i < 5 ; i++){ arrayOfTimes[i].printStandard(); cout << endl; } cout << "\n\nAddress of object t is " << &sunset << endl; cout << "Address of object dinnerTime is " << &dinnerTime << endl; cout << "Address of timePtr is " << &timePtr << endl; cout << "\nThe content of dinnerTime is "; dinnerTime.printStandard(); cout << "\nThe content of timePtr is "; timePtr->printStandard(); system("PAUSE"); return 0; Schedule: 08:30:00 AM 09:00:00 AM 11:55:15 AM 06:27:06 PM 11:58:40 PM Address of object sunset is 0x23ff20 Address of object dinnerTime is 0x23ff20 Address of timePtr is 0x23ff18 The content of dinnerTime is 06:27:06 PM The content of timePtr is 06:27:06 PM 陣列中的每個項目都是一個time物件 因為每個項目都是一個time物件,所以可以使用(.)來使用成員函式 reference: C++ How to Program 6e
9.3 Class Scope and Accessing Class Members Class scope contains Data members Variables declared in the class definition Member functions Functions declared in the class definition Nonmember functions are defined at file scope 即使成員函式的實作寫在類別定義的主體之外,仍然屬於類別使用域。 reference: C++ How to Program 6e
9.3 Class Scope and Accessing Class Members (Cont.) Within a class’s scope Class members are accessible by all member functions Member functions can call each other directly void Time::printUniversal(){ cout << setfill('0') << setw(2) << hour << ":" << setw(2) << minute << ":" << setw(2) << second; printStandard(); } Outside a class’s scope public class members are referenced through a handle An object name A reference to an object A pointer to an object reference: C++ How to Program 6e
9.3 Class Scope and Accessing Class Members (Cont.) Variables declared in a member function Have block scope Known only to that function Hiding a class-scope variable In a member function, define a variable with the same name as a variable with class scope Such a hidden variable can be accessed by preceding the name with the class name followed by the scope resolution operator (::) class A{ public: void set(){ int a; A::a = 1; } private: }; reference: C++ How to Program 6e
Access Functions and Utility Functions Can read or display data Can test the truth or falsity of conditions Such functions are often called predicate functions For example, isEmpty function for a class capable of holding many objects Utility functions (also called helper functions) private member functions that support the operation of the class’s public member functions Not part of a class’s public interface Not intended to be used by clients of a class 使用這些函式的目的是為了減少外部程式的控制結構。 Utility function在作業二有使用到 gcd(); reference: C++ How to Program 6e
Time Class Case Study: Constructors with Default Arguments Constructors can specify default arguments Can initialize data members to a consistent state Even if no values are provided in a constructor call Constructor that defaults all its arguments is also a default constructor Can be invoked with no arguments Maximum of one default constructor per class reference: C++ How to Program 6e
Prototype of a constructor with default arguments reference: C++ How to Program 6e
reference: C++ How to Program 6e
使用時要小心,要確認存取到的成員值已經設定過了。 Parameters could receive the default values 使用時要小心,要確認存取到的成員值已經設定過了。 reference: C++ How to Program 6e
reference: C++ How to Program 6e 分的越細,存取越細。 容易維護。 層層呼叫避免重複的程式碼。 reference: C++ How to Program 6e
reference: C++ How to Program 6e
Initializing Time objects using 0, 1, 2 and 3 arguments reference: C++ How to Program 6e
reference: C++ How to Program 6e
reference: C++ How to Program 6e Invalid values passed to constructor, so object t5 contains all default data reference: C++ How to Program 6e