指標與陣列

Download Report

Transcript 指標與陣列

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