在計算機科學中,指針(Pointer)是編程語言中的一個對象,利用地址,它的值直接指向(points to)存在電腦存儲器中另一個地方的值。由於通過地址能找到所需的變量單元,可以說,地址指向該變量單元。因此,將地址形象化的稱為“指針”。意思是通過它能找到以它為地址的內存單元。
在信息工程中指針是一個用來指示一個內存地址的計算機語言的變量或中央處理器(CPU)中寄存器(Register)【用來指向該內存地址所對應的變量或數組】。指針一般出現在比較接近機器語言的語言,如匯編語言或C語言。面向對象的語言如Java一般避免用指針。指針一般指向一個函數或一個變量。在使用一個指針時,一個程序既可以直接使用這個指針所儲存的內存地址,又可以使用這個地址裡儲存的函數的值
本文側重於通過幾個例子,來解析指針。
數組和指針
1、
1 int a[5]={1,2,3,4,5}; 2 int *p=(int*)(&a+1); 3 printf("%d\n",*(p-1));
/* a是一個數組名,也就是數組的首地址。 對a進行取地址運算符,得到的是一個指向數組的指針!!!!這句話尤為重要! 也就相當於 int (*p) [5] = &a; p=&a+1指向的是數組組a[4]的後面一個int單元, p-1指向a[4]=5 p是一個指針,它指向的是一個包含5個int元素的數組!! 那麼執行p+1後,p的偏移量相當於 p + sizeof(int) * 5 !! 而程序中強制將指針p轉換成一個int* 那麼 p -1 其實就是 p - sizeof(int) 所以,p -1 指向了數組中得最後一個元素,也就是 5 */
2、
int a[]={1,2,3,4,5}; int*p[]={a,a+1,a+2,a+3}; int **q=p; printf("%d\n",*(p[0]+1)+**(q+2));
/* p[0]+1=a+1; *(p[0]+1)=2; *(q+2)=a+2; *(a+2)=3; 3+2=5; 其中p[0]=a也就是a[0]的地址, p[0]+1=a+1就是a[1]的地址, *(p[0]+1)就是a[1]的值就是2, **q=p --> *q=&p -->表示q保存的是p 的地址,q+2表示p[2]的地址,*(q+2)表示p[2], **(q+2)表示*p[2]表示*(a+2)就是a[2]的值就是3, 所以 *(p[0]+1)+**(q+2)=5 */
3、
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; int (*pt)[4]=a; printf("%d\n",(*(pt+2))[2]);
/* 二維數組a[3][4]可以看做是{{1,2,3,4},{5,6,7,8},{9,10,11,12}}; (*(pt+2))[2]的值相當於 *(*(pt+2)+2) p[2]指向a[2]也就是a[2][0]的地址,所以p[2]+2指向a[2][2]的地址,其內容為11。 */
4、
int a[3][2]={1,2,3,4,5}; int *p[3]; p[0]=a[1]; printf("%d\n",*(p[0]+1));
// *(p[0]+1)所代表的數組元素是 a[1][1]
5、
static int a[]={5,4,3,2,1}; int *p[]={a+3,a+2,a+1,a}; int **q=p; printf("%d\n",*(p[0]+1)+**(q+2));
/* *(p[0] +1 ) = *( *(p+0) + 1) = *(a+3 +1) = a[4] = 1 **(q+2) = *(*(q+2) +0 ) =*( p[2]) = *(a+1) = 4;
*/
6、
int a[10]={1,2,3,4,5,6,7,8,9,10}; int *p=&a[3]; int b=p[5]; printf("%d\n",b);
/* a可以理解為這個數組的首地址 a[3]是指向第4個元素 所以p指向第4個元素 p[5]是從p後的5個 也就是第9個元素 所以b=9 */
7、
int a[2][3]={1,2,3,4,5,6}; int *p; p=a[0]; printf("%d\n",*(p+3));
// *(p+3)所代表的數組元素是 a[1][0];