# 一維陣列的指標
陣列佔據內存中一塊連續的存儲空間,每個陣列元素都有確定的內存地址; 可通過定義指向陣列元素類型的指標變數,間接訪問陣列中的各個元素。 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; | |
} |