指標(Pointer)其實是"箭頭",內容其實是位址(Address)
Pointer 和 Array 可以說是 “兄弟關係” , 關係相當緊密。
Pointer 與 一維陣列
例如:
int a [] = { 1, 2, 3, 4, 5 };
a[3] 可以represent為 *(a+3)
a[0] 可以represent為 *(a+0) or *a
<-- *a的起始值是a[0]
或者可以用一個pointer指住一個array,
e.g. int *p = a;
// 此方法只適用於一維陣列,多維陣列的宣告方法會於文章末端提及。
此時, 若a陣列記憶體位址分佈如下:
a[0] = 12000
12001
12002
12003
a[1] = 12004
12005
12006
12007
a[2] = 12008
12009
12010
12011
......
......
那
p = 12000, *p = a[0] = 1;
p+1 = 12004, *(p+1) = a[1] = 2;
p+2 = 12008, *(p+2) = a[2] = 3;
註: *p+1 和 *(p+1) 的意思是不同,
*p+1 會等於 2 , 意思是指先把*p的值
拿出來,然後再+1。
Pointer 與 多維陣列
例如:
int a[2][4] = { {1,3,5,7} , {2,4,6,8} };
陣列表示法 |
值 |
連續記憶體表示法 |
陣列索引值轉換表示法 |
a[0][0] |
1 |
**a |
*(*(a+0)+0) |
a[0][1] |
3 |
*(*a+1) |
*(*(a+0)+1) |
a[1][0] |
2 |
*(*a+4) |
*(*(a+1)+0) |
a[1][3] |
8 |
*(*a+7) |
*(*(a+1)+3) |
註:Pointer會把一個多維陣列中每欄的element都編上
一個次序,例如第一欄 {1,3,5,7} ,所得的次序就是
0-3 , 接著第二欄 {2,4,6,8} ,所得次序就是4-7。
例如 *( *a+7 ) 中,由於 *a 值是 0 , 所以*a+7 得出
是7,然後 *7 即是指排在第7元素的值,即是第二欄
的第4個element的值, 即是8。
- 在二維陣列的記憶體裡的位置是連續的儲存空間
- *( *(a+i) + j ) == a [ i ] [ j ] ;
- a[0][1][3] == *( *( *a+1)+3 ) ;
- a[1][2][3] == *( *( *(a+1) + 2 ) +3 );
Exercise:
#include <iostream.h>
void main() {
int a [3] [4] = { {1,3,5,7} , {2,4,6,8} , {10,20,30,40} };
int *p = &a[0][0];
int *pp = a[0][0];
int *p0 = a[0];
// p0的起始點會是a[0][0]
int *p1 = a[1];
// p1的起始點會是a[1][0]
int *p2 = a[2];
cout <<
*(p+4+1) << endl;
cout <<
*pp << endl;
cout <<
*(p0+2) << endl;
cout <<
*p1 <<endl;
cout <<
*(p2-2) <<endl;
cout <<
*p2[3] <<endl;
}
output:
4
1
5
2
6
40
* 常見問題!
知道一維宣告方法是
int *arr = new int[1];
但是換成了
int *arr = new int[1][1];
就出錯了,為什麼呢?
解答:
==============================
當宣告一維陣列時,可以
const int x=10;
int obj[x];
用指標宣告方法:
const int x=10;
int *obj = new int[x];
================================
但當宣告二維時,必須使用**,
以便逐一由內而外配置。
const int x=10, y=20;
int **obj;
obj = new int*[x]; // 第一次分配第一維
for(int i=0; i<x; ++i) {
obj[i] = new int [y]; // 第二次分配第二維
}
=================================
三維陣列做法一樣
const int x=10, y=20, z=5;
int ***obj;
obj = new int**[x]; // 配置一次少一個星
for(int i=0; i<x; ++i) {
obj[i] = new int*[y]; // 再配置一次,再少一個星
for(int j=0; j<y; ++j) {
obj[i][j] = new int[z]; // 再配置一次,再少一個星
}
}