資料大樓 --談指標與陣列 2008.12. 綠園
指標與陣列 陣列:是固定長度且連續的記憶體區塊。 指標:是一種特殊的變數,用來記錄所指向變數的位址。 陣列名稱本身是一個存放位址的「指標常數」,它儲存了陣列第一個元素的位址。 所以陣列的元素就可以利用指標的運算來存取。
指標與一維陣列 若宣告 int a[3]={5,7,9}; 則指標 a,所指的是a[0]的位址。 即: *a 和 a[0]的值是一樣的。
指標與一維陣列範例 #include <iostream> #include <cstdlib> using namespace std; int main(void) { int a[3]={5,7,9}; int i,sum=0; for(i=0;i<3;i++) sum += *(a+i); /* 同sum += a[i] */ cout << "sum=" << sum << endl; system("PAUSE"); return 0; }
雙重指標 指標不但可以指向任何一種資料型態的變數,還可以讓指標指向另一個指標變數,這種指向指標的指標,稱為雙重指標。 雙重指標 指標變數 一般變數 1200 1460 5 1000 1200 1460
雙重指標的宣告 雙重指標變數的宣告: 也可以這樣宣告: int **ptri; /*可指向整數的雙重指標*/ char **ptrc; /*可指向字元的雙重指標*/ 也可以這樣宣告: int *(*ptri); /*可指向整數的雙重指標*/ char *(*ptrc);/*可指向字元的雙重指標*/
雙重指標範例 int a=10, b, *p,**pp; p = &a; //圖解一 pp = &p; b = *p; cout << “a=” << a << “,b=” << b << endl; **pp = 30; //圖解三 cout <<“*p=” << *p <<“,**pp=” << **pp << endl; 執行結果: a=20,b=10 a=30,b=10 *p=30,**pp=30
雙重指標範例圖解一 int a=10, b, *p,**pp; p = &a; pp = &p; b = *p; 雙重指標 **pp 指標變數 *p 一般變數 a 10 一般變數 b int a=10, b, *p,**pp; p = &a; pp = &p; b = *p; 10
雙重指標範例圖解二 雙重指標 **pp 指標變數 *p 一般變數 a 20 一般變數 b *p = 20; 10
雙重指標範例圖解三 雙重指標 **pp 指標變數 *p 一般變數 a 30 一般變數 b **pp = 30; 10
二維陣列 vs. 雙重指標 int num[3][3]={{1,2,3},{4,5,6},{7,8,9}}; num[3][3] [0][0] [0][1] [0][2] [1][0] [1][1] [1][2] [2][0] [2][1] [2][2] 1 2 3 4 5 6 7 8 9 1000 1004 1008 1012 1016 1020 1024 1028 1032
二維陣列 vs. 雙重指標 指標常數 指標常數陣列 1 2 3 4 5 6 7 8 9 num 1000 num[0] 1000 1004 1008 4 5 6 num[1] 1012 *(num+1) 1012 1016 1020 7 8 9 num[2] 1024 *(num+2) 1024 1028 1032
二維陣列 vs. 雙重指標 1 2 3 4 5 6 7 8 9 num[3][3] num[0][0]的位址 *(num+0)+0 1000 1004 1008 4 5 6 1012 1016 1020 7 8 9 1024 1028 1032
二維陣列 vs. 雙重指標 1 2 3 4 5 6 7 8 9 num[3][3] num[0][0] *(*(num+0)+0) 1 1000 1004 1008 4 5 6 1012 1016 1020 7 8 9 1024 1028 1032
動態記憶體配置運算子 【new 與 delete】 利用 new 取得動態空間 int *ptr; ptr = new int; 可以合併寫成 int *ptr = new int(10); 利用 delete 釋放空間 delete ptr; ptr = NULL;
一維動態記憶體配置 int i, n; cin >> n; // 輸入5 // ptr 指向 n 個連續整數動態空間的首位空間位址 int *ptr = new int[n]; for(i=0; i<n; i++) *(ptr+i)=(i+1)*(i+1); n 5 ptr 0x4790 1 0x4790 4 0x4794 9 0x4798 16 0x479c 25 0x47a0 配置n個int
二維動態配置記憶體 int i, m, n; cin >> m >> n; int **ptr = new int*[m]; for(i=0; i<m; i++) ptr[i] = new int[n];
二維動態配置記憶體 …… int **ptr = new int*[m]; for(i=0; i<m; i++) ...... ptr[1][n-1] for(i=0; i<m; i++) ptr[i] = new int[n]; int * ptr[0] ptr[1] ptr[2] ..... ptr[m-1] ptr[0][0] ptr[0][1] ptr[0][2] ...... ptr[0][n-1] ptr[2][0] ptr[2][1] ptr[2][2] ...... ptr[2][n-1] …… ptr [m-1][0] [m-1][1] [m-1][2] ...... [m-1][n-1]
釋放記憶體 一維動態配置的記憶體釋放 int *ptr = new int[n]; ...... delete[] ptr; ...... delete[] ptr; ptr = NULL;
釋放記憶體 二維動態配置的記憶體釋放 int **ptr = new int*[m]; for(i=0; i<m; i++) ptr[i] = new int[n]; ...... for (i=0; i<m; i++) { delete[] ptr[i]; ptr[i] = NULL; } delete[] ptr; ptr = NULL;
指標與參照 指標:可以指向任意的同型態變數。 int i=10, j=20, *ptr; ptr = &i; ptr = &j; 參照:取得欲參考變數的位址,直接代替該變數。且一經設 定,就無法改變,必須從一而終。 int i=15, j=30; int &ref; //(X) int &ref = i; //(O) int &ref = j; //(X)
指標、參照與函數 函數傳回值為指標與參照之差異: int *func1(int *); int &func2(int &); ...... func1(a) = 100; // (X) func2(a) = 100; // (O) 因此,若是當程式中需要將函數裡的某個變數位址傳回,並為它設值時,指標就無用武之地,只能使用參照完成。