1.數組名:數組名的值是一個指針常量,也就是第一個數組元素的地址。這裏需要注意的是指針常量。編譯器用數組名記錄數組的信息(數組元素的個數等),只有在表達式中使用數組名纔會產生一個指針常量。只存在兩個特列:(1)sizeof(),返回的是數組的長度;(2)取地址操作符&,返回的是一個指向數組的指針.
int Array[5] = {1,2,3,4,5};
int *p = Array;
int *pArray = &Array;//區別在於p是數組Array[]第一個元素的地址,而*pArray是數組Array的地址
//若p 的值爲 p = 0x804a014
// pArray = 0x804a014
// p + 1 = 0x804a018
// pArray + 1 = 0x804a028
2.下標的使用:C的下標與間接訪問表達式一樣,在任何使用下標引用的地方都可以使用對等的指針表達式來代替。
*(b + 3);//其中b是一個指向整型的指針,所以b+3指向另一個整型的指針,他所指向的是數組第一個元素向後移3個整數長度的位置。
int array[10];
int *ap = array +2;
則//ap,即爲array+2,與&array[2]等價
//*ap,即爲array[2]
//ap[0] ;貌似ap不是一個指針,其實這麼想是錯誤的,c的下標引用與間接訪問表達式是一樣的,在這種情況下等價於*(ap + (0));
下面這段代碼剛好可以解釋上述問題
int main()
{
int Array[5] = { 1,2,3,4,5 };
int* p = Array;
printf("*(p+2) = %d\nArray[2] = %d\n(p+2)[2] = %d\n", *(p + 2), Array[2], (p + 2)[2]);
printf("p = %p\np + 1 = %p\n&Array = %p\n&Array + 1 = %p\n", p,p+1,&Array,&Array+1);
getchar();
return 0;
}
名稱 | 值 | 類型 | 備註 |
---|---|---|---|
*(p + 2) | 3 | int | 等價於Array[2] |
Array[2] | 3 | int | |
(p + 2)[2] | 5 | int | 等價於Array[5] |
p | 0x0097f7f4 | int * | Array[0]的地址,是一個int型指針 |
p+1 | 0x0097f7f8 | int * | Array[1]的地址,是一個int型指針 |
&Array | 0x0097f7f4 {1, 2, 3, 4, 5} | int[5] * | &Array代表的是數組指針, |
&Array+1 | 0x0097f808 {-858993460, -1684265792, 9959460, 19865726, 1} | int[5] * | 因此,&Array+1表示向後移動5個int型字節 |
效率:數組與指針的效率問題
//代碼段1
int Array[10],a;
for(a = 0; a < 10; a += 1)
Array[a] = 0;
//代碼段2
int Array[10],*ap;
for(ap = Array; ap < Array; ap++)
*ap = 0;
指針的效率不低於數組,數組的效率不高於指針。如上述代碼段1因爲數組取元素是用下標乘以類型長度,執行的乘法運算,較爲耗時;代碼段2,循環中,執行乘法運算的都是1*4,結果這個乘法就在編譯時執行過一次,——程序現在包含一條指令,把4與指針相加,而在運行時不執行乘法運算。因此在這種情況下指針效率比數組高。