1.數組指針:即指向數組的指針
那么, 如何聲明一個數組指針呢?
int (* p)[10]; /*括號是必須寫的,不然就是指針數組;10是數組的大小*/
1
拓展:有指針類型元素的數組稱為指針數組。
2.通過指針引用數組元素的基本方法
(1)小標法:a[i]。
(2)指針法:* (a+i) 或 * (p+i) 或 p[i]。其中,a是數組名,p=a,即p指向數組a首元素的地址。
問:為什么* (a+i) 和* (p+i)是等價的,或者說是引用的同一個數組元素呢?
答:在C語言中,數組名代表的是數組中首元素的地址。在程序編譯時,a[i]是按*(a+i)處理的,即按數組元素的首地址加上相應位移量i找到新元素的地址。而p=a,即p是指向數組a的首元素的地址,因此是等價的。從這里可以看出,[ ]實際上是變地址運算符,即將a[i]按a+i計算地址,然后找此地址單元中的值。
問:為什么p[i] 和* (p+i)是等價的,或者說是引用的同一個數組元素呢?
答:C語言規定,當指針變量指向數字元素時,指針變量可以帶下標。而在程序編譯時,對此下標處理的方法是轉換為地址,即對p[i] 處理成 (p+i)。同上,[ ]是變址運算符。
3.利用指針引用數組元素
(1)p++; *p;
(2)*p++;等價於*(p++);因為++和*的優先級一樣,故結合方向是從右向左。
(3)*(p++);和*(++p);二者是有區別的。前者是先取*p的值,然后p加1;后者是先p加1,再取p的值。即如果p指向的是數組a元素a[0],則前者得到a[0]的值,后者得到a[1]的值。
(4)++(*p);將p指向的元素的值加1。
(5)如果p指向元素a[i],
*(p--);先得到p指向的地址的元素a[i],然后p減1。
*(++p);執行結果得到a[i+1],p加1。
*(–p);執行結果得到a[i-1],p減1。
4.利用指針輸出數組元素
int a[10];
int * p;
p = a;
while(p<a+10)
printf("%d",*p++);
或
int a[10];
int * p;
p = a;
while(p<a+10)
{
printf("%d",*p);
p++;
}
或
int a[10];
int * p;
p = a;
for(i=0;i<10;i++)
printf("%d",*p++);
或
int a[10];
int * p;
for(p=a;p<a+10;p++) /*比較專業的寫法,代碼簡潔、高效*/
printf("%d",*p);
思考:下面代碼能不能正確輸出數組元素的值呢?
int a[10];
int * p;
for(p=a;p<a+10;a++)
printf("%d",*a);
答:是不行的。因為數組名a代表的是數組首元素的地址,是一個指針型常量,它的值在程序運行期間是不改變的,即a++是不變的。
因此,結合動態分配數組,我們可以建立一個一維的數組指針:
int (* array)[N]=(int *)malloc(N*sizeof(int));