一.陣列指標和指向陣列的指標變數
乙個變數有乙個位址,乙個陣列包含若干個元素,每個陣列元素都在記憶體中占用儲存單元,它們都有相應的位址。所謂陣列的指標是指數組的起始位址,陣列元素的指標是指數組元素的位址。
乙個陣列是由連續的一塊記憶體單元組成的,陣列名就是這款連續記憶體單元的首位址。
例:
int a[10]; //定義a為包含10個int型資料的陣列
int *p; //定義p為指向int型變數的指標
//下面兩個語句是等價的
p=&a[0];
p=a;
因為陣列是int型,所以指標變數也應為指向int型的指標變數。
p,&a[0],a均指同一記憶體單元,它們都是陣列a的首位址,也是0號元素a[0]的首位址,a,&a[0]都是常量,p是指向陣列的指標變數。
例:
int a[10];
int *p = a;
p++; //合法,p是指向陣列的指標變數
a++; //非法,a是陣列名,是陣列的首位址,是常量。
二.通過指標訪問陣列元素
如果指標變數p已經指向陣列中的乙個元素,則p+1指向同一陣列的下乙個元素。
有陣列 int [10]; int *p=&a[0]; 則:
1.p+i和a+i就是a[i]的位址,它們都指向a陣列的第i個元素。
2.*(p+i)或*(a+i)就是p+i或a+i所指向的陣列元素,即a[i]。例如*(p+5)或*(a+5)就是a[5]。
3.指向陣列的指標變數也可以帶下標,如p[i]與*(p+i)等價。
引用乙個陣列元素可以用:
1.下標法,即用a[i]形式訪問陣列元素。
2.指標法,即採用*(a+i)或*(p+i)的形式,用間接訪問的方法來訪問陣列元素,其中a是陣列名,p是指向陣列的指標變數。
例:
//通過指標法為陣列賦值並列印
int *p,i,a[10];
p=a;
for(i=0;i<10;i++)
*p++=i;
//注意此處應該加上p=a上面p的值已經不是陣列的起始位址a了
for(i=0;i<10;i++)
printf("a[%d]=%d\n",i,*p++);
指標變數可以指導到陣列以後的記憶體,系統不認為非法。
*p++等價於*(p++)
*(p++)與*(++p)不同,前者等價a[0],後者等價a[1]
(*p)++表示p所指向的元素值加1,a[0]++
如果p當前指向a陣列中的第i個元素,則
*(p--)相當於a[i--]
*(++p)相當於a[++i]
*(p++)相當於a[i++]
三.指標加減算數運算
1.對於指向陣列的指標變數,可以加上或減去乙個整數n。設pa是指向陣列a的指標變數,則pa+n,pa-n,pa++,++pa,pa--,--pa都是合法的。指標變數加減乙個整數n的意義是把指標指向的當前位置(指向某陣列元素)向前或向後移動n個位置。應當注意,陣列指標變數向前或向後移動乙個位置和位址加1減1的概念上是不同的。因為陣列可以有不同的型別,各種型別的陣列元素長度所佔的位元組長度也是不同的。如指標變數加1即向後移動1個位置標示指標指向想乙個資料元素的首位址,而不是在原位址基礎上家1,例如:
int a[5], *pa;
pa = a;
pa = pa + 2; //pa指向a[2],即pa的值是&a[2]
指標變數的加減運算只能對陣列指標變數進行,對指向其他型別的變數的指標變數做加減運算時毫無意義的。
2.對於兩個指標變數的加減運算,只有指向同一陣列的兩個指標變數之間才能進行運算,否則毫無意義。
兩個指標相減所得的差是兩個指標元素之間相差的元素個數。實際上是兩個指標值相減再除以該陣列元素的長度。
兩個指標變數相加沒有實際意義。
3.兩指標變數進行關係運算:指向同一陣列的兩指標進行關係運算可以表示他們所指元素之間的關係。例如:
pf1==pf2表示pf1和pf2指向同一陣列元素。
pf1>pf2表示pf1處於高位址位置。
pf1指標變數還可以與0比較,p==0表示p是空指標,它不指向任何變數。
對變數賦0值和不賦值是不同的。指標變數未賦值時,可以是任意值,是不能使用的,否則會造成意外錯誤。指標變數賦0值後,則可以使用,只是它不指向具體變數而已。
四.陣列名作為函式引數
指標變數的值是位址,陣列指標的變數的值即為陣列的首位址,可以作為函式的引數使用。
注意,陣列名作為函式引數傳入函式後,會自動轉換為指標。
例:
void function(int a)
void main()
; printf("sizeof(a)=%d\n",sizeof(a)); //sizeof(a)=40
function(a);
}
五.指向多維陣列的指標和指標變數
1.多維陣列的位址
設有多維陣列 inta[3][4] = ;
c語言允許把乙個二維陣列分解為多個一維陣列來處理。因此a可以分解為三個一維陣列a[0],a[1],a[2],每個陣列又含四個元素。(a是乙個包含三個陣列的陣列,每乙個元素又分別包含4個元素)。
a是二維陣列名,代表整個二維陣列的首位址,也是二維陣列0行的首位址,a+1代表第一行的首位址。
a[0]是第乙個一維陣列的陣列名和首位址,*(a+0),*a,a,a[0],&a[0][0]是等同的。
a[1]是第二個一維陣列的陣列名和首位址,*(a+1),a+1,a[1],&a[1][0]是等同的。
由此可推 *(a+i),a+i,a[i],&a[i][0]
&a[i]和a[i]也是等同的。因為在二維陣列中不能把&a[i]理解為a[i]的位址,不存在元素a[i]。c語言規定,它是一種位址計算方法,表示陣列a第i行的首位址。由此得出a[i],&a[i],*(a+i),a+i也是是等同的。
a[0]也可以看成是a[0]+0,是一維陣列a[0]的0號元素首位址,而a[0]+1則是a[0]的1號元素首位址,由此可得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)
2.指向多維陣列的指標變數
把二維陣列a分解為一維陣列a[0],a[1],a[2]後,設p為指向二維陣列的指標變數,可以定義為 int (*p)[4]; 它表示p是乙個指標變數,指向包含4個元素的一維陣列。
int (*p)[4]=a; *(p+i)+j是二維陣列i行j列元素的首位址,*(*(p+i)+j)則是i行j列元素的值。
注意:int (*p)[4];中的括號比不可少,如果沒有括號則表示是指標陣列,意義就完全不同了。
C C 陣列指標和指標陣列
陣列指標和指標陣列的區別 指標陣列 首先它是乙個陣列,每乙個元素都是乙個指標。陣列指標 首先它是乙個指標,它指向乙個陣列。它是 指向陣列的指標 的簡稱。運算子的優先順序關係 陣列指標 也稱行指標 例如 int p n 根據優先順序,先看 內,p是乙個指標,後面的 又說明了p是乙個指向陣列的指標,由於...
C C 學習筆記 指標和記憶體洩漏
c語言真是既簡單又深奧,還挺意思 今天小夥伴又有什麼問題呢?為什麼在 裡,乙個node指標在malloc一段記憶體後,需要首先memset一下,並且free掉之後,還可以通過node指標訪問到裡面的內容?下面按照關鍵點來逐條分析 為什麼要memset一下 其實程式新申請的記憶體空間中,並不能保證空間...
第五講 c c 陣列與指標
本文的編寫是為了在學習c 的時候加深自己的記憶,同時也為與我一般的初學者提供一些參考,此處特別感謝 1.陣列 陣列型別 陣列名 陣列長度 1 宣告陣列,陣列在宣告時必須定義長度以分配記憶體,如 int m array1 20 float m array2 20 char m array3 20 2 ...