Presentation is loading. Please wait.

Presentation is loading. Please wait.

第 8 章 記憶體指標. 8.0 變數、數值、位址 8.1 指標與變數 對 C++ 語言而言,指標( pointers )是存放 變數或陣列的位址,因此也可以藉由指標 間接取得變數或陣列中的值。 對 C++ 語言而言,指標( pointers )是存放 變數或陣列的位址,因此也可以藉由指標 間接取得變數或陣列中的值。

Similar presentations


Presentation on theme: "第 8 章 記憶體指標. 8.0 變數、數值、位址 8.1 指標與變數 對 C++ 語言而言,指標( pointers )是存放 變數或陣列的位址,因此也可以藉由指標 間接取得變數或陣列中的值。 對 C++ 語言而言,指標( pointers )是存放 變數或陣列的位址,因此也可以藉由指標 間接取得變數或陣列中的值。"— Presentation transcript:

1 第 8 章 記憶體指標

2 8.0 變數、數值、位址

3 8.1 指標與變數 對 C++ 語言而言,指標( pointers )是存放 變數或陣列的位址,因此也可以藉由指標 間接取得變數或陣列中的值。 對 C++ 語言而言,指標( pointers )是存放 變數或陣列的位址,因此也可以藉由指標 間接取得變數或陣列中的值。 在多個函數的程式中,使用時以變數或陣 列指標作為函數間傳遞的參數,比直接傳 送變數或陣列方便且快得多。 在多個函數的程式中,使用時以變數或陣 列指標作為函數間傳遞的參數,比直接傳 送變數或陣列方便且快得多。

4 8.1.1 宣告指標變數 指標變數 (pointer variable) 一般簡稱指標 (pointer) , 它的用途是存放記憶體的位址。 指標變數 (pointer variable) 一般簡稱指標 (pointer) , 它的用途是存放記憶體的位址。 指標變數是 C++ 提供的特殊變數,用於存取或傳 遞記憶體位址,就好像 int 是用於存取或傳遞整數 資料等。 指標變數是 C++ 提供的特殊變數,用於存取或傳 遞記憶體位址,就好像 int 是用於存取或傳遞整數 資料等。 宣告指標變數和宣告一般變數的方法類似,只是 在指標變數前面加上星號 (*) 或是在資料型態後面 加上星號 (*) 。 宣告指標變數和宣告一般變數的方法類似,只是 在指標變數前面加上星號 (*) 或是在資料型態後面 加上星號 (*) 。 資料型態 * 指標變數 ; 資料型態 * 指標變數 ;

5 8.1.1 宣告指標變數 範例 範例 int *numPtr, number;// 宣告指標變數與整數變數 int* num1Ptr, num2Ptr;// 宣告同列變數為指標變數 int number = 10;// 宣告變數 number int *numPtr;// 宣告指標 numPtr

6 8.1.2 位址運算符號 & 範例 範例 int number = 10;// 指定 number = 10 cout << &number;// 輸出 number 的位址 & 變數名稱 & 變數名稱

7 8.1.3 起始指標位址 範例 範例 int number;// 宣告變數 number int *numPtr; // 宣告指標 numPtr numPtr = &number;// 啟始指標 numPtr 資料型態 * 指標名稱 ; 指標名稱 = & 變數 ; 資料型態 * 指標名稱 ; 指標名稱 = & 變數 ;

8 8.1.3 起始指標位址 ( 續 ) int number; // 宣告變數 number int *numPtr = &number; // 宣告並啟始指標 numPtr 資料型態 * 指標名稱 = & 變數位址 ; 資料型態 * 指標名稱 = & 變數位址 ;

9 8.1.4 間接運算符號 * 範例 範例 int x; int number = 10;//number=10 int *numPtr = &number;//numPtr=number 的位址 x = *numPtr;// 間接取得資料 * 指標名稱 * 指標名稱

10 8.1.4 間接運算符號 * ( 續 ) 範例 範例 int *pointer;// 宣告指標 *pointer = 100;//100 存入指標位址

11 // 檔案名稱: d:\C++08\C0803.cpp #include void main(void) { bool boolVar = true;// 宣告與起始布林值變數 int intVar = 65536;// 宣告與起始整數變數 float floatVar = 123.45f;// 宣告與起始單精度變數 double doubleVar = 98765.43;// 宣告與起始倍精度變數 bool* boolPtr = &boolVar;// 設定 boolVar 指標 int* intPtr = &intVar;// 設定 intVar 指標 float* floatPtr = &floatVar;// 設定 floatVar 指標 double* doublePtr = &doubleVar;// 設定 doubleVar 指標 cout << " 變數名稱 \t 變數位址 \t 變數指標 \n";// 輸出表頭 cout << "---------\t--------\t--------\n";// 輸出分隔線 // 輸出變數名稱、位址、與指標 cout << "bool \t" << &boolVar << '\t' << boolPtr << endl; cout << "intVar \t" << &intVar << '\t' << intPtr << endl; cout << "floatVar \t" << &floatVar << '\t' << floatPtr << endl; cout << "doubleVar\t" << &doubleVar << '\t' << doublePtr << endl; }

12 執行結果

13 8.1.5 長度運算符號 sizeof 長度運算符號是用來取得變數或指標所佔的記憶體 長度 ( 以 byte 為單位 ) sizeof 長度運算符號是用來取得變數或指標所佔的記憶體 長度 ( 以 byte 為單位 ) 可以取得陣列中的元素個數 可以取得陣列中的元素個數 sizeof 變數名稱 sizeof 變數名稱 sizeof array / sizeof array[0] sizeof array / sizeof array[0]

14 8.1.5 長度運算符號 範例 範例 cout << sizeof(bool);// 輸出 bool 型態的長度 1 cout << sizeof(int);// 輸出 int 型態的長度 4 cout << sizeof(float);// 輸出 float 型態的長度 4 cout << sizeof(double);// 輸出 double 型態的長度 8 char *array[] = {" 床前明月光, ", " 疑似地上霜; ", " 舉頭望明月, ", " 低頭思故鄉。 " }; // 宣告陣列指標 int count = (sizeof array)/(sizeof array[0]); // 計算元素個數

15 8.2 指標與陣列 指標與變數的關係還算單純,但指標與陣 列的關係就複雜多了。 指標與變數的關係還算單純,但指標與陣 列的關係就複雜多了。 陣列名稱本身就是指標,所以可以直接將 陣列名稱當作指標來使用外,還可將陣列 名稱指定給另外的指標。 陣列名稱本身就是指標,所以可以直接將 陣列名稱當作指標來使用外,還可將陣列 名稱指定給另外的指標。 字串陣列又與一般數值陣列不盡相同,所 以字串陣列指標的用法又有些許差異。 字串陣列又與一般數值陣列不盡相同,所 以字串陣列指標的用法又有些許差異。

16 8.2.1 陣列指標 int array[10];// 宣告陣列 array int *arrayPtr;// 宣告指標 arrayPtr arrayPtr = array;// 啟始指標 arrayPtr int array[10];// 宣告陣列 array int *arrayPtr = array;// 宣告並啟始指標 arrayPtr 資料型態 * 指標名稱 ; 指標名稱 = 陣列名稱 ; 資料型態 * 指標名稱 ; 指標名稱 = 陣列名稱 ; 資料型態 * 指標名稱 = 陣列名稱 ; 資料型態 * 指標名稱 = 陣列名稱 ;

17 8.2.2 陣列元素指標 範例 範例 short array[ ] = {30, 47, 26, 17, 22, 23}; short *arrayPtr;// 宣告陣列指標 arrayPtr = &array[0];// 起始陣列指標 cout << "array 的第 0 個元素是: " << *arrayPtr; arrayPtr = &array[1];// 更新陣列指標 cout << "array 的第 1 個元素是: " << *arrayPtr; arrayPtr = &array[2];// 更新陣列指標 cout << "array 的第 2 個元素是: " << *arrayPtr; 資料型態 * 指標名稱 = & 陣列名稱 [ 註標 ]; 資料型態 * 指標名稱 = & 陣列名稱 [ 註標 ];

18 // 檔案名稱: d:\C++08\C0806.cpp #include void main(void) { short array[] = {30, 47, 26, 17, 22, 23};// 宣告字串變數 short *arrayPtr;// 宣告浮點數指標 const int SIZE = (sizeof array)/(sizeof array[0]); // 計算陣列個數 for(int i=0; i<SIZE; i++) { arrayPtr = &array[i];// 更新指標位置 cout << "array 的第 " << i << " 個元素是: "; cout << *arrayPtr << endl;// 輸出指標位置資料 }

19 執行結果

20 8.2.3 指標運算 範例 範例 short array[] = {30, 47, 26, 17, 22, 23};// 宣告字串變數 cout << "array[0]=" << *array;// 輸出 array[0]=30 cout << "array[1]=" << *(array+1);// 輸出 array[1]=47 cout << "array[3]=" << *(array+3);// 輸出 array[3]=17 cout << "array[5]=" << *(array+5);// 輸出 array[5]=23 *( 陣列名稱 +n) *( 陣列名稱 +n)

21 8.2.3 指標運算 ( 續 ) 範例 範例 short array[] = {30, 47, 26, 17, 22, 23}; cout << "array[0]+1 = " << *array+1; // 輸出 array[0]+1=30+1=31 cout << "array[1]+3 = " << *(array+1)+3; // 輸出 array[1]+3=47+3=50 cout << "array[3]-5 = " << *(array+3)-5; // 輸出 array[3]-5=17-5=12 * 指標名稱 + n// 等於 (* 指標名稱 )+n * 指標名稱 - n// 等於 (* 指標名稱 )-n * 指標名稱 + n// 等於 (* 指標名稱 )+n * 指標名稱 - n// 等於 (* 指標名稱 )-n

22 8.2.4 指標增減 範例 範例 short array[] = {30, 47, 26, 17, 22, 23};// 宣告字串變數 short *arrayPtr = &array[0];// 指標 =array[0] 位址 cout << "array 的第 0 個元素 =" << *arrayPtr; // 輸出第 0 元素 =30 cout << "array 的第 1 個元素 =" << *(++arrayPtr); // 輸出第 1 元素 =47 cout << "array 的第 2 個元素 =" << *(++arrayPtr); // 輸出第 2 元素 =26 cout << "array 的第 3 個元素 =" << *(++arrayPtr); // 輸出第 3 元素 =17 ++ 指標名稱 | 指標名稱 ++ ++ 指標名稱 | 指標名稱 ++ -- 指標名稱 | 指標名稱 -- -- 指標名稱 | 指標名稱 --

23 8.2.4 指標增減 ( 續 ) 範例 範例 short array[] = {30, 47, 26, 17, 22, 23};// 宣告字串變數 short *arrayPtr = array;// 指標 =array 起始位址 cout << "array 的第 0 個元素 =" << *arrayPtr; // 輸出第 0 元素 =30 cout << "array 的第 1 個元素 =" << *(arrayPtr+=1); // 輸出第 1 元素 =47 cout << "array 的第 4 個元素 =" << *(arrayPtr+=3); // 輸出第 3 元素 =22 指標名稱 +=n 指標名稱 +=n 指標名稱 -=n 指標名稱 -=n

24 8.2.5 字串指標 char string[] = "ANSI/ISO C++";//string 為字串變數 char *pstring = "Visual C++";//pstring 為字串指標 cout << string;// 顯示字串變數值 cout << pstring;// 顯示指標位址到字串結束 cout << string[7];// 顯示字串第 7 元素值 cout << pstring + 7;// 顯示指標第 7 元素至結束 char* 字串名稱 = " 字串資料 "; char* 字串名稱 = " 字串資料 ";

25 8.2.5 字串指標 ( 續 ) 範例 範例 char array[4][20] = { " 床前明月光 ", " 疑似地上霜 ", " 疑似地上霜 ", " 舉頭望明月 ", " 舉頭望明月 ", " 低頭思故鄉 " }; // 宣告二維字串陣列 " 低頭思故鄉 " }; // 宣告二維字串陣列 char *parray [4] = { " 床前明月光 ", " 疑似地上霜 ", " 疑似地上霜 ", " 舉頭望明月 ", " 舉頭望明月 ", " 低頭思故鄉 " }; // 宣告一維字串指標 " 低頭思故鄉 " }; // 宣告一維字串指標 char* 字串名稱 [ 長度 ] = { " 字串 0", " 字串 1", " 字串 2",... }; char* 字串名稱 [ 長度 ] = { " 字串 0", " 字串 1", " 字串 2",... };

26 8.2.5 字串指標 ( 續 ) 範例續 範例續 cout << array[2]// 顯示 (2,0) 字串 << parray[2]// 顯示 (2,0) 指標 << array[1][4] << array[1][5]// 顯示第 (1,4) 與 (1,5) 字元 << parray[1]+4;// 顯示 (1,4) 指標至結束

27 Ex 17 寫一 C++ 程式,宣告一個整數變數並設定 初值,另宣告一個指標變數,將指標變數 的值設為整數變數的位址,請輸出整數變 數的值和整數變數的位址,以及指標變數 的值和指標變數的位址。 寫一 C++ 程式,宣告一個整數變數並設定 初值,另宣告一個指標變數,將指標變數 的值設為整數變數的位址,請輸出整數變 數的值和整數變數的位址,以及指標變數 的值和指標變數的位址。

28 8.3 指標與函數 傳遞變數指標 傳遞變數指標 傳遞陣列指標 傳遞陣列指標 傳遞常數指標 傳遞常數指標 傳遞字串指標 傳遞字串指標 傳回函數指標 傳回函數指標

29 8.3.1 傳遞變數指標 傳遞變數值( pass-by-value ) 傳遞變數值( pass-by-value ) void main( ) { int var1 = 53, var2 = 75; swap(var1, var2); } void swap(int num1, int num2) { int buffer; buffer = num1; num1 = num2; num2 = buffer; } int num1 = var1 = 53; int num2 = var2 = 75;

30 8.3.1 傳遞變數指標 ( 續 ) 傳遞變數指標( pass-by-reference ) 傳遞變數指標( pass-by-reference ) int &num1 = var1; int &num2 = var2;

31 8.3.1 傳遞變數指標 函數名稱 ( 變數指標 );// 呼叫敘述 傳回型態 函數名稱 ( 參數型態 * 參數名稱 ) { // 函數本體 }

32 8.3.1 傳遞變數指標 ( 續 ) 傳遞變數指標一 傳遞變數指標一 int *num1 = &var1; int *num2 = &var2;

33 8.3.1 傳遞變數指標 ( 續 ) 傳遞變數指標二 傳遞變數指標二 int *num1 = pvar1; int *num2 = pvar2;

34 8.3.2 傳遞陣列指標 函數名稱 ( 陣列指標 );// 呼叫敘述 傳回型態 函數名稱 ( 參數型態 * 參數名稱 ) { // 函數本體 } 傳遞陣列指標與傳遞變數指標的函數宣告與函數呼叫 是一樣的,只是呼叫時參數改為陣列名稱。

35 8.3.2 傳遞陣列指標 ( 續 ) 範例 範例 void main(void) { int source[3] = {5, 9, 3}; showArray(source);// 呼叫 showArray 函數 } void showArray(int *array)// 函數, 參數為陣列指標 { for (int i=0; i<=2; i++)// 輸出迴圈 cout << *(array+i) << endl; // 依序輸出 source 陣列元素 }

36 8.3.2 傳遞陣列指標 ( 續 ) 函數名稱 ( 陣列名稱 );// 呼叫敘述 傳回型態 函數名稱 ( 參數型態 參數名稱 []) { // 函數本體 } 與第七章傳遞陣列名稱完全相同

37 8.3.2 傳遞陣列指標 ( 續 ) 範例 範例 void main(void) { int source[3] = {5, 9, 3}; showArray(source);// 呼叫 showArray 函數 } void showArray(int array[])// 函數, 參數為整個陣列 { for (int i=0; i<=2; i++)// 輸出迴圈 cout << array[i] << endl; // 依序輸出 source 陣列元素 }

38 8.3.3 傳遞常數指標 函數名稱 ( 常數指標 );// 呼叫敘述 傳回型態 函數名稱 (const 參數型態 * 參數名稱 ) { // 函數本體 }

39 8.3.3 傳遞常數指標 ( 續 ) 範例一 範例一 void power(const int *);// 計算平方函數原型 void main(void) { const int LEN = 5;// 宣告整常數符號 power(&LEN);// 傳遞常數指標 } void power(const int *NUM)// 計算平方函數 { cout << *NUM * *NUM; }

40 8.3.3 傳遞常數指標 ( 續 ) 範例二 範例二 void power(const int *);// 計算平方函數原型 void main(void) { int LEN = 5;// 宣告整整數變數 power(&LEN); // 傳指呼叫, 傳遞變數位址 } void power(const int *NUM)// 接收指標常數 { cout << *NUM * *NUM; }

41 8.3.4 傳遞字串指標 函數名稱 ( 字串指標 );// 呼叫敘述 傳回型態 函數名稱 (char * 參數名稱 ) { // 函數本體 }

42 8.3.4 傳遞字串指標 ( 續 ) 範例 範例 void main(void) { char *str = "You will never win, if you never begin."; toString(str);// 傳遞 str 指標給 toString } void toString(char *s)// 輸出字串函數 { cout << s << endl; }

43 // 檔案名稱: d:\C++08\C0817.cpp #include void capital(char *);// 宣告函數原型 void main(void) { char str[] = "You will never win, if you never begin.\n"; char *strPtr = &str[0];// 宣告並起始 C 字串指標 cout << " 資料列: " << str; capital(strPtr);// 傳遞字串指標給 capital cout << " 更改後: " << str; } void capital(char *s)// 第一個字母改大寫函數 { while(*s != NULL)// 若不是字串結尾則繼續 if(*s++ == ' ') {// 若 *s == ' ' *s -= 32;// 則 *s++ -= 32 }

44 執行結果

45 8.3.5 傳回函數指標 * 函數名稱 ( 參數 );// 呼叫敘述 傳回型態 * 函數名稱 ( 參數列 )// 函數表頭 { // 函數本體 }

46 8.3.5 傳回函數指標 ( 續 ) 範例 範例 void main(void) { cout << *getNumber();// 取得 getNumber() 指標值 } float *getNumber()// 輸入浮點數函數 { float *num; cin >> *num; return num; }

47 8.4 動態記憶體 C++ 語言沒有垃圾回收的功能,所以程式不會自 動釋放不再使用的變數或陣列記憶體。因此如果 程式配置變數或陣列愈多,則佔據的記憶體就愈 多,當然也就影響程式可用的空間,以及影響程 式執行的速度。 C++ 語言沒有垃圾回收的功能,所以程式不會自 動釋放不再使用的變數或陣列記憶體。因此如果 程式配置變數或陣列愈多,則佔據的記憶體就愈 多,當然也就影響程式可用的空間,以及影響程 式執行的速度。 程式設計師如果認為有些變數或陣列可以於用完 後立即釋放佔用空間,則可以使用配置動態記憶 體的方式來配置動態記憶體變數或陣列。 程式設計師如果認為有些變數或陣列可以於用完 後立即釋放佔用空間,則可以使用配置動態記憶 體的方式來配置動態記憶體變數或陣列。

48 8.4.1 配置動態記憶體 new 變數指標 = new 資料型態 ( 起始資料 ); 變數指標 = new 資料型態 ( 起始資料 ); 範例一 範例一 int num = 100; int *numPtr = &num;//*numPtr 指向 num 變數 範例二 範例二 int *newPtr;// 宣告指標變數 newPtr = new int;// 配置動態指標變數 *newPtr = 200;// 起始指標變數值 =200 範例三 範例三 int *newPtr = new int(200);//*newPtr 內值 =200

49 8.4.2 釋放動態記憶體 delete delete 變數指標 ; delete 變數指標 ; 範例 範例 int *p;// 宣告指標 *p = 100;// 起始指標的內值 cout << *p << endl; p = new int(200);// 配置動態記憶體給指標 cout << *p << endl; delete p;// 釋放指標佔用的動態記憶體

50 8.4.3 配置動態陣列 陣列指標 = new 資料型態 [ 長度 ]; 陣列指標 = new 資料型態 [ 長度 ]; 範例 範例 int p[10];// 宣告整數陣列 p[10]; int i; for(i=0; i<10; i++) p[i] = i;// 起始陣列初值 for(i=0; i<10; i++) cout << p[i] << ' ';// 輸出陣列元素值

51 8.4.4 釋放動態陣列 delete [] 陣列指標 ; delete [] 陣列指標 ; 範例 範例 int *p = new int[10];// 等於 int p[10]; int i; for(i=0; i<10; i++) p[i] = i;// 起始陣列初值 for(i=0; i<10; i++) cout << p[i] << ' ';// 輸出陣列元素值 delete [ ] p;// 釋放陣列記憶體

52 // 檔案名稱: d:\C++08\C0820.cpp #include void main(void) { int *p = new int[10];// 等於 int p[10]; int i; for(i=0; i<10; i++) p[i] = i;// 起始陣列初值 cout << " 輸出陣列元素值: "; for(i=0; i<10; i++) cout << p[i] << ' ';// 輸出陣列元素值 delete [] p;// 釋放陣列記憶體 }

53 執行結果

54 Ex 18 寫一 C++ 程式,找尋輸入值中的最大值。 寫一 C++ 程式,找尋輸入值中的最大值。 定義一個 maximum 函數,接收呼叫敘述傳遞的 陣列參數,找尋陣列中的最大值,並傳回最大 值的指標給呼叫敘述。 定義一個 maximum 函數,接收呼叫敘述傳遞的 陣列參數,找尋陣列中的最大值,並傳回最大 值的指標給呼叫敘述。 在 mail 函數中,定義一個浮點數值列,然後呼 叫並傳遞陣列指標給 Maximum 函數,最後輸出 傳回的最大值。 在 mail 函數中,定義一個浮點數值列,然後呼 叫並傳遞陣列指標給 Maximum 函數,最後輸出 傳回的最大值。

55 Homework 7 寫一個 C++ 程式,檢查字串是否為對稱字。 寫一個 C++ 程式,檢查字串是否為對稱字。 定義一個 responsed 函數,接收呼叫敘述傳遞的字 串陣列參數,然後比較該字串是否為對稱自 ( 例 如 ada 、 abba 、 noon 等 ) ,最後傳回 true 或 false 給呼 叫敘述。 定義一個 responsed 函數,接收呼叫敘述傳遞的字 串陣列參數,然後比較該字串是否為對稱自 ( 例 如 ada 、 abba 、 noon 等 ) ,最後傳回 true 或 false 給呼 叫敘述。 在 main 函數中,定義一個字串指標,由鍵盤輸入 一字串並存入指標位址,然後呼叫並傳遞字串給 responsed 函數,取得 true 或 false 後輸出是否為對 稱字。 在 main 函數中,定義一個字串指標,由鍵盤輸入 一字串並存入指標位址,然後呼叫並傳遞字串給 responsed 函數,取得 true 或 false 後輸出是否為對 稱字。


Download ppt "第 8 章 記憶體指標. 8.0 變數、數值、位址 8.1 指標與變數 對 C++ 語言而言,指標( pointers )是存放 變數或陣列的位址,因此也可以藉由指標 間接取得變數或陣列中的值。 對 C++ 語言而言,指標( pointers )是存放 變數或陣列的位址,因此也可以藉由指標 間接取得變數或陣列中的值。"

Similar presentations


Ads by Google