陣列指標 指標陣列
1、陣列指標(指向陣列的指標)
(1)陣列在記憶體中的表示
建立一個陣列就是在記憶體裡面開闢一塊連續的空間,比如int a[4];就是在記憶體裡面開闢了一個大小為4*sizeof(int)位元組的記憶體空間。二維陣列是特殊的一維陣列。
先來看一段程式碼:
<strong><span style="font-size:16px;">void main()
{
int a[2][2]={1,2,3,4};//這是一個2*2的二維陣列
int (*p)[2];//陣列指標
p=a;//令p指向陣列a
}</span></strong>
注意到程式碼中這句話:int (*p)[2];這裡的p是一個陣列指標變數。
a中各個元素在記憶體中是這樣存放的:
(2)理解陣列名和陣列指標變數
OK,現在我們思考a,a[0],a[1],p,a+1,a[0]+1,p+1到底是什麼,思考3秒鐘:
分析:
a是一個陣列名,型別是指向一維陣列的指標,不是變數,a的值是指標常量,即不能有a++或者a=p這些操作。a指向這塊連續空間的首地址,值是&a[0][0]。
a[0]是一維陣列名,型別是指向整型的指標,值是&a[0][0],這個值是一個常量。
a[1]是一維陣列名,型別是指向整型的指標,值是&a[1][0],這個值是一個常量。
p是一個陣列指標變數,指向一維陣列的指標變數,值是&a[0][0]。可以執行p++;p=a等操作。
a+1表示指向下一行元素,也可以理解為指向下一個一維陣列。
*(a+1)是取出第一行的首地址。
a[0]+1是指向第0行第1個元素,也可以理解為指向一維陣列a[0]的第一個元素。
p+1同a+1
*(p+1)同*(a+1)
雖然a跟a[0]值是一樣,但型別不一樣,表示的意義不一樣。通過分析就不難理解為什麼*(*(a+i)+j)和a[i][j]等效了。
(3)指標是陣列的迭代器
<span style="font-size:16px;">#include<stdio.h>
#define M 2
#define N 3
int main()
{
int a[M][N]={1,2,3,4,5,6};
int *start=&a[0][0];
int * const end=start+M*N;
for(;start!=end;start++)
printf("%-5d",*start);
putchar('\n');
return 0;
}</span>
理解這段程式碼,用指標遍歷一個二維陣列,是不是很像C++標準庫裡面vector的迭代器。注意這裡只用了一個for迴圈,這也可以說明二維陣列其實就是特殊的一維陣列。
(4)陣列名與陣列指標變數的區別
從(2)中的分析中得出陣列名是指標,型別是指向元素型別的指標,但值是指標常量,宣告陣列時編譯器會為宣告所指定的元素數量保留記憶體空間。陣列指標是指向陣列的指標,宣告指標變數時編譯器只為指標本身保留記憶體空間。
看看這個程式碼:
<strong><span style="font-size:16px;">#include<stdio.h>
void main()
{
int a[2][2]={1,2,3,4};//這是一個2*2的二維陣列
int (*p)[2];//陣列指標
p=a;//令p指向陣列a
printf("%d\n%d\n",sizeof a,sizeof p);
}</span></strong>
猜一猜輸出是什麼?
困惑了嗎?為什麼結果會是這樣的呢,讓我們先初步瞭解一下sizeof關鍵字吧,下面是MSDN上sizeof的說明:
注意到說明中的紅色字型,當sizeof用於變數時返回這個變數佔用的實際空間的大小。當sizeof用於陣列名時,返回整個陣列的大小(這裡的大小指佔用的位元組數)。p是一個指標變數,這個變數佔用四個位元組。而a是陣列名,所以sizeof a返回陣列a中的全部元素佔用的位元組數。
瞭解了sizeof,猜猜下面這段程式碼輸出什麼
<span style="font-size:16px;"><strong>#include<stdio.h>
void main()
{
int a[2][2]={1,2,3,4};//這是一個2*2的二維陣列
int (*p)[2];//陣列指標
p=a;//令p指向陣列a
printf("%d\n%d\n",sizeof(a+1),sizeof(p+1));
printf("%d\n%d\n",sizeof(a+0),sizeof(p+0));
}</strong></span>
執行結果:
從結果中看出,a在做+運算時是轉化成了指標變數,此時a+i的型別是一個指標變數,而不是一個陣列名。但a[i]是一個一維陣列的陣列名,sizeof(a[0])的值是8。
現在再來看一段程式碼:
<strong><span style="font-size:16px;">#include<stdio.h>
void f(int a[][2])
{
printf("%d\n",sizeof a);
}
void main()
{
int a[2][2]={1,2,3,4};//這是一個2*2的二維陣列
printf("%d\n",sizeof a);
f(a);
}</span></strong>
再猜一下輸出是什麼?
是不是又有點困惑呢?
解釋:這是因為傳參的時候陣列名轉化成指標變數,注意到函式f中f(int a[][2])這裡並不需要指定二維陣列的長度,此處可以改為int (*a)[2]。所以傳過來的就是一個陣列指標變數。這樣明白了吧!
總結:陣列名的型別是指向元素型別的指標,值是指標常量。(a+1)的型別是一個指標變數。把陣列名作為引數傳遞的時候實際上傳遞的是一個指標變數。sizeof對變數和陣列名操作時返回的結果會不一樣。陣列指標是指向陣列的指標,其值可以是變數。
2、指標陣列(存放指標的陣列)
(1)認識指標陣列
一個存放int型別的陣列稱為整型陣列,那麼存放指標的陣列就叫指標陣列。
<strong><span style="font-size:16px;">#include<stdio.h>
void main()
{
int i=1,j=2;
//p先跟[]結合,然後再跟*結合
int *p[2];//指標陣列,存放指標的陣列
p[0]=&i;
p[1]=&j;
printf("%d",sizeof(p));
}</span></strong>
斷點除錯分析:
此例陣列p就兩個元素,p[0]是指向i的指標,p[1]是指向j的指標。這兩個指標都是int型指標,所以p是存放int型指標的陣列。sizeof(p)返回陣列佔用的總空間,所以程式輸出是8
(2)指標陣列用法舉例
來自《the c programming language》的一個例子,對字串進行排序,看了下面這個例子,相信你就體會到了指標陣列的好處了。
3、深入思考
陣列名a、a[0]、a[1],陣列指標p到底在記憶體中是怎麼儲存的呢?存放在記憶體中的哪裡呢?是在程式碼段嗎?求解惑!
4、參考資料
《c和指標》 《the c programming language》 等
源地址:http://blog.csdn.net/touch_2011/article/details/6966980
另外的一篇文章
陣列指標(也稱行指標)
定義 int (*p)[n];
()優先順序高,首先說明p是一個指標,指向一個整型的一維陣列,這個一維陣列的長度是n,也可以說是p的步長。也就是說執行p+1時,p要跨過n個整型資料的長度。
如要將二維陣列賦給一指標,應這樣賦值:
int a[3][4];
int (*p)[4]; //該語句是定義一個陣列指標,指向含4個元素的一維陣列。
p=a; //將該二維陣列的首地址賦給p,也就是a[0]或&a[0][0]
p++; //該語句執行過後,也就是p=p+1;p跨過行a[0][]指向了行a[1][]
所以陣列指標也稱指向一維陣列的指標,亦稱行指標。
指標陣列
定義 int *p[n];
[]優先順序高,先與p結合成為一個陣列,再由int*說明這是一個整型指標陣列,它有n個指標型別的陣列元素。這裡執行p+1是錯誤的,這樣賦值也是錯誤的:p=a;因為p是個不可知的表示,只存在p[0]、p[1]、p[2]...p[n-1],而且它們分別是指標變數可以用來存放變數地址。但可以這樣 *p=a; 這裡*p表示指標陣列第一個元素的值,a的首地址的值。
如要將二維陣列賦給一指標陣列:
int *p[3];
int a[3][4];
for(i=0;i<3;i++)
p[i]=a[i];
這裡int *p[3] 表示一個一維陣列記憶體放著三個指標變數,分別是p[0]、p[1]、p[2]
所以要分別賦值。
這樣兩者的區別就豁然開朗了,陣列指標只是一個指標變數,似乎是C語言裡專門用來指向二維陣列的,它佔有記憶體中一個指標的儲存空間。指標陣列是多個指標變數,以陣列形式存在記憶體當中,佔有多個指標的儲存空間。
還需要說明的一點就是,同時用來指向二維陣列時,其引用和用陣列名引用都是一樣的。
比如要表示陣列中i行j列一個元素:
*(p[i]+j)、*(*(p+i)+j)、(*(p+i))[j]、p[i][j]
優先順序:()>[]>*
源地址:http://www.cnblogs.com/hongcha717/archive/2010/10/24/1859780.html
相關文章
- 陣列指標,指標陣列陣列指標
- 指標陣列與陣列指標指標陣列
- 指標陣列和陣列指標與二維陣列指標陣列
- Go 陣列指標(指向陣列的指標)Go陣列指標
- 陣列指標陣列指標
- Golang 學習——陣列指標和指標陣列的區別Golang陣列指標
- C陣列和指標陣列指標
- C語言指標(三):陣列指標和字串指標C語言指標陣列字串
- 二維陣列與指標陣列指標
- 透過指標引用陣列指標陣列
- 【原創】淺談指標(十三)指向陣列的指標指標陣列
- C語言 指標與陣列C語言指標陣列
- 指標陣列練習排列字串指標陣列字串
- 二維陣列的指標的理解陣列指標
- c語言-運算子,陣列,指標C語言陣列指標
- c程式設計--指標與陣列C程式程式設計指標陣列
- 陣列,函式與指標 詳解陣列函式指標
- 日常學習儲存--陣列和指標陣列指標
- 【C】 28_指標和陣列分析(上)指標陣列
- 【C進階】28、指標和陣列分析指標陣列
- 雙指標查詢陣列的連續規律子陣列問題指標陣列
- C----陣列越界問題、指標入門陣列指標
- 關於二維陣列指標的問題陣列指標
- C指標和陣列的關係詳解指標陣列
- C語言指標和陣列筆試題C語言指標陣列筆試
- 【原創】淺談指標(九)二維陣列和多級指標相關指標陣列
- LeetCode合併兩個有序陣列(逆向雙指標)LeetCode陣列指標
- 要點1:指標、陣列和複合字面量指標陣列
- 3-6指標與陣列的天生姻緣指標陣列
- (C語言)使用指標列印陣列的內容C語言指標陣列
- 物聯網學習教程— 多維陣列與指標陣列指標
- 陣列地址與指標之間的區別與聯絡陣列指標
- 二級指標,二維陣列函式引數傳遞指標陣列函式
- 6.PHP包含檔案、終止指令碼、陣列指標PHP指令碼陣列指標
- sizeof和strlen計算陣列型別和指標型別字串陣列型別指標字串
- hdu 1277 AC自動機入門(指標版和陣列版)指標陣列
- 劍指 offer(1) -- 陣列篇陣列
- 資料結構與演算法基礎之指標和陣列資料結構演算法指標陣列
- C語言系列之 指標與陣列總複習視訊教程C語言指標陣列