chap 8 指標

61
1 1 /61 /61 Chap 8 Chap 8 指指 指指 指指 指指 (pointer) (pointer) 指指指指指指指指指 指指指指 一, 指指指指指指指指指 指指指指 一, 指指指指指指 指指指指指 一體。 指指指指指指 指指指指指 一體。 指指指指指指指 指指指指指指指 指指指指指指指 指指指指指指指 指指指指指指指 指指指指指指指 指指指指指指指 指指指指指指指 指指指指指指 指指指指指指 (803~852 (803~852

Upload: cameo

Post on 19-Mar-2016

49 views

Category:

Documents


1 download

DESCRIPTION

Chap 8 指標. 清明時節雨紛紛 路上行人欲斷魂 借問酒家何處有 牧童遙指杏花村 《 清明 ﹒ 杜牧 (803~852)》. 指標 (pointer) 是一種特別的資料型態,用來儲存某一資料在記憶體內的位址。. 指標. 8.1  記憶體位址與指標 8.2  指標與參照 8.3  陣列與指標的代數計算 8.4  指標參數 8.5  函數指標 8.6  動態記憶體配置. 在記憶體內資料的四個相關特性. 1. 資料名稱。 2. 資料型態。 3. 資料內容。 4. 該資料在記憶體內的位址。. 變數 A 的內容和位址. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Chap 8    指標

11/61/61

Chap 8 Chap 8 指標指標

指標 指標 (pointer) (pointer) 是一種特別的資料型態,是一種特別的資料型態,用來儲存某一資料在記憶體內的位址。用來儲存某一資料在記憶體內的位址。

清明時節雨紛紛 路上行人欲斷魂清明時節雨紛紛 路上行人欲斷魂借問酒家何處有 牧童遙指杏花村借問酒家何處有 牧童遙指杏花村 《清明﹒杜牧 《清明﹒杜牧 (803~852)(803~852) 》》

Page 2: Chap 8    指標

22/61/61

指標 指標 8.18.1  記憶體位址與指標  記憶體位址與指標 8.28.2  指標與參照 指標與參照 8.38.3  陣列與指標的代數計算  陣列與指標的代數計算 8.48.4  指標參數 指標參數 8.58.5  函數指標 函數指標 8.68.6  動態記憶體配置  動態記憶體配置

Page 3: Chap 8    指標

33/61/61

在記憶體內資料的四個相關特性在記憶體內資料的四個相關特性 1.1. 資料名稱。資料名稱。 2.2. 資料型態。資料型態。 3.3. 資料內容。資料內容。 4.4. 該資料在記憶體內的位址。該資料在記憶體內的位址。

Page 4: Chap 8    指標

44/61/61

變數 變數 A A 的內容和位址 的內容和位址 double A = 2.5double A = 2.5// // 定義 定義 doubledouble 變數變數 AA 並存入 並存入 2.52.5

0x0065FE00

2.5

A

4 bytes

Page 5: Chap 8    指標

55/61/61

範例程式 範例程式 Variable.cppVariable.cpp // Variable.cpp #include <iostream>using namespace std;// ----- 主程式 ------------------------int main(){ double A = 2.5; cout << "A 的值為: " << A << endl; cout << "A 所佔用的記憶體大小為: " << sizeof(A) << " bytes 或是 " << sizeof(double) << " bytes" << endl; cout << "A 所在位址為: " << “0x” << &A << endl; return 0;}

Page 6: Chap 8    指標

66/61/61

操作結果 操作結果 A 的值為: 2.5A 所佔用的記憶體大小為: 8 bytes 或是 8 bytesA 所在位址為: 0x0012FF84

Page 7: Chap 8    指標

77/61/61

指標 指標 指標是用來儲存其他資料的位址的特殊代號。例如,指標是用來儲存其他資料的位址的特殊代號。例如,我們可以使用以下敘述來定義一個名叫 我們可以使用以下敘述來定義一個名叫 pFpF 的指標:的指標: double A = 2.5;double A = 2.5; double* pF; // double* pF; // 定義指標 定義指標 pFpF pF = &A; // pF = &A; // 將資料 將資料 A A 的位址的位址存入指標 存入指標 pFpF 具體表示如下:具體表示如下:

Page 8: Chap 8    指標

88/61/61

指標的四個特性指標的四個特性 對於指標 對於指標 pFpF 而言,它的而言,它的

名稱: 名稱: pFpF資料型態: 資料型態: double *double *

資料內容: 資料內容: 0x0065FE00 0x0065FE00

記憶體位址: 記憶體位址: 0x0065FDFC0x0065FDFC

Page 9: Chap 8    指標

99/61/61

宣告時所指定的目標資料的資料型態無法改變宣告時所指定的目標資料的資料型態無法改變譬如,譬如, pF pF 已宣告為已宣告為double* pF;double* pF;      // // 定義指標 定義指標 pFpF假如假如int X = 12; int X = 12; 則敘述則敘述pF = &X; // pF = &X; // 錯誤錯誤 ! ! 指標 指標 pF pF 必需存放 必需存放 double double 資料的位址資料的位址必需配合目標資料的資料型態改成必需配合目標資料的資料型態改成

int* pF;int* pF;

Page 10: Chap 8    指標

1010/61/61

指標 指標 pF pF 指向變數 指向變數 AA

指標指標 pFpF 和變數和變數 AA 之間的關係之間的關係

0x0065FE00 0x0065FDFC

2.5

A pF

Page 11: Chap 8    指標

1111/61/61

指標的定義 指標的定義 指標的定義敘述有兩種寫法:指標的定義敘述有兩種寫法:

double* pFdouble* pF ; ; // // 定義指標 定義指標 pF (pF ( 較常用較常用 ))

double *pFdouble *pF ; ; // // 定義指標 定義指標 pF (pF ( 較少用較少用 ))

同時定義兩個指標: 同時定義兩個指標: double *p1, *p2; // double *p1, *p2; // 同時定義同時定義 p1, p2p1, p2 兩個指標兩個指標

在定義在定義 pFpF 的同時給予初值:的同時給予初值:double* pF = &Adouble* pF = &A ; ; // // 定義指標定義指標 pFpF ,同時存入資料 ,同時存入資料 A A 的位址的位址

Page 12: Chap 8    指標

1212/61/61

取值運算子 取值運算子 (value-of operator)(value-of operator)

double x; double x; // // 定義 定義 double double 變數 變數 xxx = *pFx = *pF ; ; // // 將指標 將指標 pFpF 所指處的資料存到變數 所指處的資料存到變數 xx表示的是「將存在指標表示的是「將存在指標 pFpF 所指之處的內容儲存到所指之處的內容儲存到 xx 裹面」。裹面」。

Page 13: Chap 8    指標

1313/61/61

變數指標變數指標double* pF;double* pF; // // 定義指標定義指標 pFpF

double X, Ydouble X, Y ;;pF = &X;pF = &X; // pF // pF 指向 指向 XXpF = &Y;pF = &Y; // pF // pF 改指向 改指向 YY允許好幾個指標指向同一個資料。例如:允許好幾個指標指向同一個資料。例如: double *pF1, *pF2; double X = 1.0; pF1 = &X; pF2 = &X;

pF1

pF2 1.0

X

Page 14: Chap 8    指標

1414/61/61

陣列名稱也是指標陣列名稱也是指標double V[5]; double V[5]; // // 定義陣列 定義陣列 VV

VV 是一個常數指標 是一個常數指標 (constant pointer)(constant pointer) ,,資料型態為資料型態為 double * constdouble * const 。。

V V[0] V[1] V[2] V[3] V[4]

Page 15: Chap 8    指標

1515/61/61

指標與取址運算子指標與取址運算子 (address-of operator) (address-of operator) 「「 && 」」 double X = 3.8; double X = 3.8; // // 宣告和初始化 宣告和初始化 XXdouble* p = &X; double* p = &X; // // 宣告和初始化 宣告和初始化 pp其關係相當於其關係相當於

*p *p 是 是 X X 的內容 的內容 (( 亦即上圖中的 亦即上圖中的 3.8) 3.8) &X &X 是 是 p p 的內容 的內容 (( 亦即 亦即 X X 的位址 的位址 0x0065FE00)0x0065FE00) 。。

3.8

X

p

0x0065FE00

Page 16: Chap 8    指標

1616/61/61

參照參照double &x = y;double &x = y; // // 宣告宣告 x x 是 是 y y 的參照的參照double &x;double &x; // // 錯誤錯誤 ! ! 必需給 必需給 x x 參照的對象參照的對象double y, z;// double y, z;// 定義 定義 y y 和 和 z z 兩個 兩個 double double

變數變數double &x = z;double &x = z; // // 錯誤錯誤 ! ! 不能更改參照的對不能更改參照的對

象象

Page 17: Chap 8    指標

1717/61/61

範例程式 範例程式 Ref.cpp Ref.cpp 使用參照和指標使用參照和指標 // Ref.cpp#include <iostream>using namespace std;// ------ 主程式 -----------------------int main(){ double x = 1.0; double &y = x; // 定義 x的參照 y double *p = &x; // 定義和初始化指標 p cout << "x 原來的值是 " << x << endl; *p = 5.0; cout << "執行 *p = 5.0; 後 \n"; cout << "x 的值是 " << x << endl; y = 7.3; cout << "執行 y = 7.3; 後 \n"; cout << "x 的值是 " << x << endl; return 0;}

Page 18: Chap 8    指標

1818/61/61

操作結果 操作結果 x 原來的值是 1

執行 *p = 5.0; 後x 的值是 5

執行 y = 7.3; 後x 的值是 7.3

Page 19: Chap 8    指標

1919/61/61

使用下標來計算陣列元素的位址使用下標來計算陣列元素的位址const int m = 5;const int m = 5;

double A[m];double A[m];

則第則第 k+1k+1 個元素,也就是個元素,也就是 A[k] A[k] 的位址的位址為 為

&A[0] + k × sizeof(double)&A[0] + k × sizeof(double)

Page 20: Chap 8    指標

2020/61/61

使用下標來計算陣列元素的位址使用下標來計算陣列元素的位址const int m = 20;const int m = 20;

const int n = 60;const int n = 60;

double B[m][n];double B[m][n];

元素元素 B[i][j] B[i][j] 的位址為的位址為&B[0][0] + (i × n + j) × sizeo&B[0][0] + (i × n + j) × sizeof(double)f(double)

Page 21: Chap 8    指標

2121/61/61

使用下標來計算陣列元素的位址使用下標來計算陣列元素的位址const int m = 20;const int m = 20;const int n = 60;const int n = 60;const int p = 80;const int p = 80;double C[m][n][p];double C[m][n][p];元素元素 C[i][j][k]C[i][j][k] 的位址為的位址為&C[0][0][0] + (i × n × p + j × &C[0][0][0] + (i × n × p + j × p + k) × sizeof(double) p + k) × sizeof(double)

Page 22: Chap 8    指標

2222/61/61

使用指標來存取 使用指標來存取 A[0] A[0] 的位址的位址 double *pV;double *pV;則下面兩式都可以將則下面兩式都可以將 A[0] A[0] 的位址存到的位址存到 pVpV 裏面:裏面:pV = &A[0];pV = &A[0];pV = A;pV = A;

一維陣列一維陣列 (( 向量向量 )) 和指標變數和指標變數 pVpV 之間的關係 之間的關係 pV A[0] A[1] A[2] A[3] A[4]

Page 23: Chap 8    指標

2323/61/61

使用指標來存取陣列元素:使用指標來存取陣列元素:指標代數 指標代數 (pointer algebra)(pointer algebra)

*pV *pV 相當於 相當於 A[0]A[0]

*(pV+i) *(pV+i)   相當於   相當於 A[i]A[i]

我們可以寫成通式:我們可以寫成通式:A[i] ≡ *(pV+i) A[i] ≡ *(pV+i) 這裹這裹 ii的範圍為 的範圍為 0 ~ 0 ~

(m-1)(m-1)。 。

Page 24: Chap 8    指標

2424/61/61

範例程式 範例程式 Apointer.cpp (Apointer.cpp ( 指標代數指標代數 )) 使用使用 *pV++ *pV++ 逐一獲得向量的各個元素,以求得向量逐一獲得向量的各個元素,以求得向量的總合的總合

// Apointer.cpp#include <iostream>using namespace std;// ----- 主程式 ---------------------------------int main(){ const int Size = 5; double V[Size] = {48.4, 39.8, 40.5, 42.6, 41.2}; double Sum = 0.0, Average; double *pV = V; int i; for (i=0; i<Size; i++) Sum += *pV++; cout << "陣列 V 各元素的總合是 : " << Sum << endl; cout << "陣列 V 各元素的平均值是 : " << Sum / double(Size) << endl; return 0;}

Page 25: Chap 8    指標

2525/61/61

操作結果 操作結果

陣列 V 各元素的總合是 : 212.5

陣列 V 各元素的平均值是: 42.5

Page 26: Chap 8    指標

2626/61/61

二維陣列的指標二維陣列的指標const int m = 2;const int m = 2;const int n = 3;const int n = 3;double B[m][n];double B[m][n];

二維陣列二維陣列 BB 的儲存方式及相關的指標的儲存方式及相關的指標

B

B[0] B[1]

B[0][0] B[0][1] ... B[1][0] B[1][1] ...

Page 27: Chap 8    指標

2727/61/61

二維陣列的元素表示法二維陣列的元素表示法

通式:通式:B[i][j] ≡ *(B[i] + j) ≡ *(*(B+i) + j)B[i][j] ≡ *(B[i] + j) ≡ *(*(B+i) + j)

下標表示法 指標表示法 (1) 指標表示法 (2)

B[0][0] *B[0] *(*B)

B[0][1] *(B[0]+1) *(*B+1)

B[0][2] *(B[0]+2) *(*B+2)

B[1][0] *B[1] *(*(B+1))

B[1][1] *(B[1]+1) *(*(B+1)+1)

B[1][2] *(B[1]+2) *(*(B+1)+2)

Page 28: Chap 8    指標

2828/61/61

範例程式 範例程式 ShowMatrix.cpp ShowMatrix.cpp (( 指標表示法指標表示法 ))

#include <iomanip>#include <iostream>using namespace std;// -----------------------------------int main(){ const int Row = 2; const int Col = 3; double B[Row][Col]={ 1.8, 4.9, 6.8, 6.2, 2.1, 3.4}; int i, j; cout << "(1)陣列 B 是 : " << endl; for (int i=0; i< Row; i++) { for (int j=0; j< Col; j++) cout << setw(5) << B[i][j]; cout << endl; }

Page 29: Chap 8    指標

2929/61/61

cout << endl; cout << "(2)陣列 B 是 : " << endl; for (int i=0; i< Row; i++) { for (int j=0; j< Col; j++) cout << setw(5) << *(B[i] + j); cout << endl; } cout << endl; cout << "(3)陣列 B 是 : " << endl; for (int i=0; i< Row; i++) { for (int j=0; j< Col; j++) cout << setw(5) << *(*(B+i) + j); cout << endl; } return 0;}

Page 30: Chap 8    指標

3030/61/61

操作結果 操作結果 (1)陣列 B 是:1.8 4.9 6.86.2 2.1 3.4(2)陣列 B 是:1.8 4.9 6.86.2 2.1 3.4(3)陣列 B 是:1.8 4.9 6.86.2 2.1 3.4

Page 31: Chap 8    指標

3131/61/61

使用參照時,從呼叫端無從辨別參數有使用參照時,從呼叫端無從辨別參數有沒有使用參照沒有使用參照例如,如果在呼叫這一側的敘述寫成例如,如果在呼叫這一側的敘述寫成X = Fnc(a, b); /X = Fnc(a, b); // / 呼叫函數呼叫函數 Fnc()Fnc()被呼叫側的函數其原型可能是下列兩者中的被呼叫側的函數其原型可能是下列兩者中的任一個:任一個:

double Fnc(double, double);double Fnc(double, double);double Fnc(double&, double&);double Fnc(double&, double&);

Page 32: Chap 8    指標

3232/61/61

傳址(傳址( Passing AddressesPassing Addresses ))在呼叫端可以直接將位址當成參數:在呼叫端可以直接將位址當成參數:

X = Fnc(&a, &b); // X = Fnc(&a, &b); // 呼叫函數呼叫函數 Fnc()Fnc() ,, // // 參數用參數用 a a 和 和 b b 的位址的位址

而在接收端就可以使用指標來接受這個位址:而在接收端就可以使用指標來接受這個位址:double Fnc(double*, double*); //double Fnc(double*, double*); // 參數列是指參數列是指

標標

Page 33: Chap 8    指標

3333/61/61

範例程式 範例程式 Swap2F.cppSwap2F.cpp使用傳址的方式來交換變數的值使用傳址的方式來交換變數的值// Swap2F.cpp#include <iostream>using namespace std;// --- 函數 SwapF () 的宣告 ----------------void SwapF(double* x, double* y);// --- 主程式 -----------------------------int main(){ double a = 2, b = 5; cout << "執行 SwapF() 前 , \n"; cout << " a 是 : " << a << " b 是 : " << b << endl; SwapF(&a, &b); cout << "執行 SwapF() 後 , \n"; cout << " a 是 : " << a << " b 是 : " << b; return 0;}

Page 34: Chap 8    指標

3434/61/61

// --- 函數 SwapF () 的定義 ----------------void SwapF(double* x, double* y){ double Temp; Temp = *x; *x = *y; *y = Temp; return;}

Page 35: Chap 8    指標

3535/61/61

操作結果 操作結果 執行 SwapF() 前 ,

a 是: 2 b 是: 5

執行 SwapF() 後 ,

a 是: 5 b 是: 2

Page 36: Chap 8    指標

3636/61/61

傳遞指標以存取陣列傳遞指標以存取陣列將陣列當成函數的參數傳遞將陣列當成函數的參數傳遞

double VecAvg,double VecAvg, P[5]; // PP[5]; // P 是長度為是長度為 5 5

的一維陣列的一維陣列VecAvg = Average(P); // VecAvg = Average(P); // 呼叫函數 呼叫函數 AverAver

age()age()

而被呼叫函數的原型可寫成:而被呼叫函數的原型可寫成:double Average(double []); double Average(double []);

double Average(double *);double Average(double *);

Page 37: Chap 8    指標

3737/61/61

範例程式 檔案 範例程式 檔案 ArrayPFnc.cppArrayPFnc.cpp // ArrayPFnc.cpp#include <iostream>using namespace std;// ---函數 Average()和 MaxElem()的宣告double Average(double *);double MaxElem(double *);const int Size = 5;// ---主程式 ------------------------int main(){ double P[Size] = {48.4, 39.8, 40.5, 42.6, 41.2}; cout << "陣列 P 的平均值是 : " << Average(P) << endl; cout << "陣列 P 的最大值是 : " << MaxElem(P) << endl; return 0;}

Page 38: Chap 8    指標

3838/61/61

// ---函數 Average() 的定義 ----------double Average(double* V){ double Sum = 0; for (int i = 0; i < Size; i++) Sum += V[i]; return Sum/double(Size);}// ---函數 MaxElem() 的定義 ----------double MaxElem(double* V){ double MaxE; MaxE = V[0]; for (int i = 1; i < Size; i++ ) if (MaxE < V[i]) MaxE = V[i]; return MaxE;}

Page 39: Chap 8    指標

3939/61/61

操作結果 操作結果

陣列 P 的平均值是: 42.5

陣列 P 的最大值是: 48.4

Page 40: Chap 8    指標

4040/61/61

函數指標 函數指標 (Function Pointers)(Function Pointers)

函數名稱本身就是一種常數指標 函數名稱本身就是一種常數指標 (constant pointer)(constant pointer) 。。double Func(int);double Func(int); // // 函數 函數 Func( )Func( ) 的原型的原型

可以使用下列的語法定義函數指標可以使用下列的語法定義函數指標 pFpF 並指向函數 並指向函數 Func()Func() ::double(*pF)(int); double(*pF)(int); // // 定義函數指標定義函數指標 pF pF

pF = Func; pF = Func; // // 將函數指標將函數指標 pFpF 指向函數 指向函數 Func( )Func( )

上面兩式可以合併成一個具初始化功能的定義敘述:上面兩式可以合併成一個具初始化功能的定義敘述:double(*pF)(int) = Func;double(*pF)(int) = Func;

Page 41: Chap 8    指標

4141/61/61

函數指標的使用方式函數指標的使用方式

cont << pF(6) << endl;cont << pF(6) << endl;

Page 42: Chap 8    指標

4242/61/61

函數指標的使用 函數指標的使用 例如,把數值積分的演算法寫成函數 例如,把數值積分的演算法寫成函數 Integ()Integ() ::

double Integ(double (*Fnc)(double));double Integ(double (*Fnc)(double));對於不同的數學函數,譬如對於不同的數學函數,譬如double Fnc1(double); double Fnc1(double); // // 數學函數數學函數 Fnc1() Fnc1() 的原型的原型double Fnc2(double); double Fnc2(double); // // 數學函數數學函數 Fnc2() Fnc2() 的原型的原型這兩個數學函數的積分值:這兩個數學函數的積分值:double x1, x2; double x1, x2; // // 宣告實數 宣告實數 x1 x1 和 和 xx22

x1 = Integ(Fnc1); x1 = Integ(Fnc1); // // 計算計算 Fnc1() Fnc1() 的積分值的積分值x2 = Integ(Fnc2); x2 = Integ(Fnc2); // // 計算計算 Fnc2() Fnc2() 的積分值的積分值

Page 43: Chap 8    指標

4343/61/61

範例程式 範例程式 FncPoint.cpp FncPoint.cpp 函數指標的使用函數指標的使用 // FncPoint.cpp#include <iostream>using namespace std;// --- 函數 F1(), F2()和 Twice() 的宣告 --double F1(int);double F2(int);double Twice(double (*)(int), int);// --- 主程式 ---------------------------int main(){ int A = 3; int B = 5; cout << "Twice(F1, A)的值是 : " << Twice(F1, A) << endl; cout << "Twice(F2, B)的值是 : " << Twice(F2, B) << endl; return 0;}

Page 44: Chap 8    指標

4444/61/61

// ---- 函數 F1()的定義 ---------------------double F1(int N) { return double (N*N);}// ---- 函數 F2()的定義 ---------------------double F2(int N) { return double (N*N*N);}// --- 函數 Twice()的定義 ------------------double Twice(double (*pF)(int), int N) {return 2.0 * double( pF(N) );}

Page 45: Chap 8    指標

4545/61/61

操作結果 操作結果

Twice(F1, A)的值是: 18

Twice(F2, B)的值是: 250

Page 46: Chap 8    指標

4646/61/61

一維陣列的動態記憶體配置及回收一維陣列的動態記憶體配置及回收int Size = 100;int Size = 100;double *pV = new double[Size];double *pV = new double[Size];double *pV;double *pV;pV = new double[Size];pV = new double[Size];delete [] pV; delete [] pV;

Page 47: Chap 8    指標

4747/61/61

使用動態記憶體配置以避免大量資料使用動態記憶體配置以避免大量資料的搬移的搬移

B

B[0] B[1] B[2] B[3] B[4] A

B

A[0] A[1] A[2] A[3] A[4] A

指標內容交換後

指標內容交換前

Page 48: Chap 8    指標

4848/61/61

範例程式 範例程式 SwapV.cpp SwapV.cpp 交換指標內容以交換陣列交換指標內容以交換陣列 // SwapV.cpp#include <iostream>#include <iomanip>using namespace std;// ---函數的宣告 --------------------void DisplayV1(double*, int);void DisplayV2(double*, int);void Swap(double** x, double** y);// ---主程式 ------------------------int main(){ const int SizeA = 5; const int SizeB = 7; double* A = new double [SizeA]; double* B = new double [SizeB]; for (int i=0; i<SizeA; i++) A[i]= 1.0*i; for (int i=0; i<SizeB; i++) B[i]= 3.0*i; cout << "執行 Swap() 前 , \n"; cout << "A 是 :\n";

Page 49: Chap 8    指標

4949/61/61

DisplayV1(A, SizeA); cout << "B 是 :\n"; DisplayV2(B, SizeB); Swap(&A,&B); cout << "執行 Swap() 後 , \n"; cout << "A 是 :\n"; DisplayV1(A, SizeB); cout << "B 是 :\n"; DisplayV2(B, SizeA); delete [] A; delete [] B; return 0;}

// ------ 函數 DisplayV1()的定義 -------------void DisplayV1(double* V, int N){ cout << endl; for(int i = 0; i < N; i++) cout << setw(5) << V[i] << " "; cout << endl; return;}}

Page 50: Chap 8    指標

5050/61/61

// ------- 函數 DisplayV2()的定義 -------------void DisplayV2(double* V, int N){ cout << endl; for(int i = 0; i < N; i++) cout << setw(5) << *(V+i) << " "; cout << endl; return;}// -------- 函數 Swap()的定義 -----------------void Swap(double** x, double** y){ double* Temp; Temp = *x; *x = *y; *y = Temp;}

Page 51: Chap 8    指標

5151/61/61

操作結果操作結果執行 Swap() 前 , A 是 : 0 1 2 3 4 B 是 : 0 3 6 9 12 15 18 執行 Swap() 後 , A 是 : 0 3 6 9 12 15 18 B 是 : 0 1 2 3 4

Page 52: Chap 8    指標

5252/61/61

以逐列的方式建構二維陣列以逐列的方式建構二維陣列int m = 20, n = 50;int m = 20, n = 50;// // 動態配置長度為 動態配置長度為 m m 的一維指標陣列的一維指標陣列double **pM = new double *[m]; double **pM = new double *[m]; for (int i=0; i<m; i++)for (int i=0; i<m; i++)pM[i] = new double[n]; pM[i] = new double[n]; // // 回收二維陣列的記憶體回收二維陣列的記憶體for (int i=0; i<m; i++)for (int i=0; i<m; i++) delete pM[i];delete pM[i];delete pM;delete pM;

Page 53: Chap 8    指標

5353/61/61

二維陣列的動態記憶體配置二維陣列的動態記憶體配置(( 以逐列的方式建構二維陣列以逐列的方式建構二維陣列 ))

pM[0] pM[1]

. . .

pM[m-2] pM[m-1]

pM[0][0] pM[0][1] pM[0][2] pM[0][3] ... pM[0][n-1]

pM

pM[1][0] pM[1][1] pM[1][2] pM[1][3] ... pM[1][n-1]

pM[m-1][0]pM[m-1][1] ... pM[m-1][n-1]

.

.

.

Page 54: Chap 8    指標

5454/61/61

以連續記憶空間的方式建構二維陣列以連續記憶空間的方式建構二維陣列

pM

pM[0] pM[1]

. . .

pM[m-2] pM[m-1]

pM[0][0] pM[0][1]... pM[1][0] pM[1][1] ... pM[2][0]

Page 55: Chap 8    指標

5555/61/61

以連續記憶空間的方式建構二維陣列以連續記憶空間的方式建構二維陣列 int m = 20, n = 50;int m = 20, n = 50;// // 動態配置長度為 動態配置長度為 m m 的一維指標陣列的一維指標陣列double **pM = new double *[m]; double **pM = new double *[m]; pM[0] = new double [m*n];pM[0] = new double [m*n]; // pM[0]// pM[0] 指向新指向新向量的開頭處向量的開頭處for (int i=1; i<m; i++)for (int i=1; i<m; i++) pM[i] = pM[i-1]+n;pM[i] = pM[i-1]+n; // // 每個每個 pM[i]pM[i] 指指向陣列的特殊向陣列的特殊delete pM[0];delete pM[0]; // // 釋放指標釋放指標 pM[0]pM[0] 所指的向量所指的向量delete pM;delete pM; // // 釋放釋放 pMpM 所指的指標向量所指的指標向量

Page 56: Chap 8    指標

5656/61/61

範例程式 範例程式 DynMatrix.cpp DynMatrix.cpp 向量和矩陣用在檢查亂數的平均值向量和矩陣用在檢查亂數的平均值// DynMatrix.cpp#include <iomanip>#include <iostream>#include <new>using namespace std;const int m = 2;const int n = 3;// --- 各函數的宣告 ------------------------void ShowMatrix(double **);double MatrixAvg (double **);void Sum(double **, double **, double **);void LackMemory(){ cerr << "記憶體不足 !\n"; abort();}

Page 57: Chap 8    指標

5757/61/61

// --- 主程式 -----------------------------int main(){ // 動態記憶體配置 pMa set_new_handler(LackMemory); double **pMa = new double *[m]; for (int i=0; i<m; i++) pMa[i] = new double[n]; for (int i=0; i< m; i++) for (int j=0; j< n; j++) pMa[i][j]= (i*i+2.0*j)/2.0; // 動態記憶體配置 pMb double **pMb = new double *[m]; pMb[0] = new double [m*n]; for (int i=1; i<m; i++) pMb[i] = pMb[i-1]+n; for (int i=0; i< m; i++) for (int j=0; j< n; j++) pMb[i][j] = double(i+j)/2.0;

Page 58: Chap 8    指標

5858/61/61

// 動態記憶體配置 pMc double **pMc = new double *[m]; pMc[0] = new double [m*n]; for (int i=1; i<m; i++) pMc[i] = pMc[i-1]+n;// 顯示 pMa 和 pMb cout << "陣列 pMa 是 : " << endl; ShowMatrix(pMa); cout << "陣列 pMb 是 : " << endl; ShowMatrix(pMb); // 求 pMc Sum(pMa, pMb, pMc); cout << "陣列 pMa + pMb 是 : " << endl; ShowMatrix(pMc); // 求 pMa 的平均值 cout << "陣列 pMa 的平均值是 : " << MatrixAvg(pMa) << endl;// 回收 pMa for (int i=0; i<m; i++) delete [] pMa[i]; delete [] pMa;

Page 59: Chap 8    指標

5959/61/61

// 回收 pMb delete [] pMb[0]; delete [] pMb; // 回收 pMc delete [] pMc[0]; delete [] pMc; return 0;}// --- 函數 ShowMatrix() 的定義 -----------void ShowMatrix(double **M){ for (int i=0; i< m; i++) { for (int j=0; j< n; j++) cout << setw(5) << M[i][j]; cout << endl; } cout << endl; return;}

Page 60: Chap 8    指標

6060/61/61

// --- 函數 MatrixAvg() 的定義 ------------double MatrixAvg(double **M){ double Sum = 0; for (int i=0; i< m; i++) for (int j=0; j< n; j++)

Sum+= M[i][j]; return Sum / double(m*n);}// --- 函數 Sum() 的定義 -------------------void Sum(double **X, double **Y, double **Z){ for (int i=0; i< m; i++) for (int j=0; j< n; j++) Z[i][j]= X[i][j]+Y[i][j]; return;}

Page 61: Chap 8    指標

6161/61/61

程式 程式 DynMatrix.cpp DynMatrix.cpp 操作結果操作結果陣列 pMa是:0 1 20.51.52.5陣列 pMb是:00.5 10.511.5陣列 pMa + pMb是:01.5 312.5 4陣列 pMa的平均值是: 1.25