# 一維陣列的指標
陣列佔據內存中一塊連續的存儲空間,每個陣列元素都有確定的內存地址; 可通過定義指向陣列元素類型的指標變數,間接訪問陣列中的各個元素。 C++ 語言規定,陣列名代表陣列的首地址(即陣列中第一個元素的地址),它是一個常數指標。
int a[10], *p=a; |
a 是一個整數陣列, p 是一個整數型的指標變數,且 p 指向 a 陣列,其中 a 為陣列名,代表陣列的首地址即為 &a[0]
# 指標的算術運算
- 指標 ± 整數 -> 指標
int a[10]={10,20,30}, *p=a, i; | |
cout<<*p<<endl; | |
p++; //p 指向 a [1] | |
cout<<*p<<endl; | |
p++; //p 指向 a [2] |
示意圖:
| 指標位置 | 地址 | 值 | 變數名 |
|---|---|---|---|
| p ➡️ | 1000 | 10 | a[0] |
| p ➡️ | 1004 | 20 | a[1] |
| p ➡️ | 1008 | 30 | a[2] |
| ... | .... | ... | ... |
| p ➡️ | 1024 | a[9] |
p+i:表示p所指元素之後的第i個元素的指標p-i:表示p所指元素之前的第i個元素的指標
- 指標的算術運算與數學中運算不同。
如p的初值為a[0]的地址,即1000,執行p++後,p將指向a[1]元素,這時p的值為1004,而不是1001。 - 實際上,在 C++ 中指針的算術運算與指針指向的變量類型有關。
如p指向int型,因int型變量為 4 字節長度,所以,p+1相當於p+4,同樣p+i相當於p+i*4。
- 指標 2 - 指標 1 -> 整數
兩個同類型的指標做減法運算,常用於計算兩個指標之間包含元素的個數。
計算方法:(指針 2 - 指針 1)/ 元素的字節長度
如: p1 、 p2 是整型指標, p1 中的地址為 1000 , p2 中的地址為 1008 。
那麼 p2-p1 ,相當於 (1008-1000)/4 ,結果為 2 ,說明 p1 到 p2 之間包含 2 個元素。
# 指針類型的關係運算
即兩個指標可以比較大小。 (將指標看作整數)
例如:使用指標輸出陣列各元素值。
double x[5]={1,2,3.5,4,5.7},*p; | |
for(p=x;p<x+5;p++) { | |
cout<<*p<<"\t"; | |
} | |
cout<<endl; |
這裡使用指標變數 p 作循環控制變數,循環條件 p<x+5 為指標的關係運算,其中 x+5 表示 &x[5] 。
# 陣列元素的指標法表示
int a[10],*Ptr=a,i; |
∵ a[i] 的地址可以用 a+i 表示(即陣列的首地址 + i),
對地址 a+i 進行間接訪問運算,即 *(a+i) ,
而 *(a+i) 又解釋為指標 a+i 所指向的對象,即 a[i] ,
∴ a[i] 與 *(a+i) 的表示是等價的 。
其中: a[i] 稱為陣列元素的下標法表示,而 *(a+i) 稱為陣列元素的指
標法表示。
又 Ptr 指向陣列首地址,所以 *(a+i) 與 *(Ptr+i) 等價。
從而: a[i] , *(a+i) , *(Ptr+i) 和 Ptr[i] 的四種形式均等價。
例如:使用陣列元素不同的表示形式輸出陣列元素的值
int a[10]={1,2,3,4,5,6,7,8,9,10},*p=a,i; | |
// 下標法 | |
cout<<"a[i]"<<"\t"<<"p[i]"<<endl; | |
for(i=0;i<10;i++) { | |
cout<<a[i]<<"\t"<<p[i]<<endl; | |
} | |
// 指標法 | |
cout<<"*(a+i)"<<"\t"<<"*(p+i)"<<endl; | |
for(i=0;i<10;i++) { | |
cout<<*(a+i)<<"\t"<<*(p+i)<<endl; | |
} |
# 二維陣列的指標
int a[3][4],i,j; |
- 二維陣列 a 中 i 行 j 列元素的地址:
&a[i][j]二維陣列在內存中映射為一個一維陣列,
因此可以通過指向元素的指標,快速訪問二維陣列中的每個元素。
例子:利用指向陣列元素類型的指標變數p,尋找 a 陣列中元素的最大值
int *p, max=a[0][0]; | |
for(p=&a[0][0];p<&a[0][0]+12;p++) | |
{ | |
if(*p>max) | |
{ | |
max=*p; | |
} | |
} | |
cout<<"max="<<max<<endl; |
- 二維陣列的行地址
int a[3][4]; |
由 3 行元素組成,即 a - a[0] 、 a[1] 、 a[2] 而每行又由 4 個類型相同的元素組成,分別對應一個一維陣列。
| 行 | 對應陣列 | |||
|---|---|---|---|---|
a[0] | a[0][0] | a[0][1] | a[0][2] | a[0][3] |
a[1] | a[1][0] | a[1][1] | a[1][2] | a[1][3] |
a[2] | a[2][0] | a[2][1] | a[2][2] | a[2][3] |
其中: a 為行元素陣列的名字,即 a 代表 &a[0] , 即 0 行的地址 a+1 代表 &a[1] ,即 1 行的地址 a+2 代表 &a[2] ,即 2 行的地址。
# 二維陣列的指標表示法
由於 a[0] 是由 a[0][0] , a[0][1] , a[0][2] 和 a[0][3] 四個元素構成的一維陣列。
因此, a[0] 代表 &a[0][0] ,即 0 行的首元素的地址。 這樣 a[0]+1 代表首元素的下一個元素的地址,即 &a[0][1] ;而 a[0]+j 就代表 &a[0][j] 。
同理, a[1] 代表 &a[1][0] ,即 1 行的首元素的地址;而 a[1]+j 代表 &a[1][j] 。
同理, a[1] 代表 &a[1][0] ,即 1 行的首元素的地址;而 a[1]+j 代表 &a[1][j] 。 a[i] 代表 &a[i][0] ,即 i 行的首元素的地址;而 a[i]+j 代表 &a[i][j] 。 由此我們得到: *(a[i]+j) 等價於 a[i][j] 又由於 a[i] 等價於 *(a+i) , 因此, *(a[i]+j)) 也等價於 *(*(a+i)+j) 即: *(*(a+i)+j) 與 a[i][j] 等價。
我們將 *(*(a+i)+j) 稱為二維陣列元素 a[i][j] 的指標法表示。 其中, a 為首行地址, a+i 為 i 行的行地址,而 *(a+i) 為 a 的 i 行 0 列元素的 地址, 而 *(a+i)+j 為 a 的 i 行 j 列元素的地址。
# 指向具有 M 個元素的一維陣列指標
<型態> (*<指標變數>)[M]; //M 為一整數 |
通常利用該指標變數,指向二維陣列的行地址,其中 M 表示二維陣列的列數。
例如:利用行指標變數,按行輸出二維陣列各元素值。
int a[3][4]={ {1,3,5,7},{2,4,6,8},{1,2,3,4} },(*p)[4]; | |
for(p=a;p<a+3;p++) | |
{ | |
// 輸出 p 所指行的各列元素值 | |
for(int j=0;j<4;j++) | |
{ | |
cout<<*(*p+j)<<"\t"; | |
} | |
cout<<endl; | |
} |
int a[3][4]={ {1,3,5,7},{2,4,6,8},{1,2,3,4} },(*p)[4]; | |
for( p=a;p<a+3;p++) | |
{ | |
// 輸出 p 所指行的各列元素值 | |
for(int *q=*p;q<*p+4;q++) { | |
cout<<*q<<"\t"; | |
} | |
cout<<endl; | |
} |