1. 程式人生 > >C語言中int *p[n]和int (*p)[n]的區別

C語言中int *p[n]和int (*p)[n]的區別

前言

  1. 本博文基於VC++6.0開發除錯執行;

int *p[n] 分析:

分析這個問題要先從字元優先順序開始,在字元優先順序表中,[]的優先順序大於*,所以,int *p[n] 就等價於int *(p[n]),這樣就清晰多了,再進化一下就是 (int *)(p[n]) ,這樣就完整了,顯然,*(int )(p[n]) 就是一個數組,是一個數據型別整型字元型(int * ),以n個整型地址為元素,陣列名為p的陣列;
舉個例子:

#include <stdio.h>

void main()
{
	int a=1,b=2,c=3,d=4;
	int *p[4] = {&a,&b,&c,&d};	
	//1
	printf("%d\n",&a);
	printf("%d\n",&b);
	printf("%d\n",&c);
	printf("%d\n",&d);
	//2
	printf("\n");
	printf("%d\n",p);
	printf("%d\n",p+1);
	printf("%d\n",p+2);
	printf("%d\n",p+3);
	//3
	printf("\n");
	printf("%d\n",*p);
	printf("%d\n",*(p+1));
	printf("%d\n",*(p+2));
	printf("%d\n",*(p+3));
	//4
	printf("\n");
	printf("%d\n",**p);
	printf("%d\n",**(p+1));
	printf("%d\n",**(p+2));
	printf("%d\n",**(p+3));
}

執行結果:
在這裡插入圖片描述

由程式碼和執行結果可以看出來:

  1. 由1和2分析可知:編譯器為整型變數a,b,c,d和陣列p分別分配了不同的地址和空間;
  2. 由1和3分析可知:陣列p內的元素正是整型變數a,b,c,d的儲存地址;
  3. 由4分析可知:符號p不僅是陣列名,還是一個二重指標,並且本身指向陣列首元素(變數a的地址)的儲存地址;

所以:int *p[n] 就是一個指標陣列,資料型別為int *,元素為地址(變數地址,陣列地址,函式地址等);

int (*p)[n]分析:

規則同上,先從運算子優先順序的角度來分析結構,()和[]具有相同的優先順序,但是符號是從左向右,所以可以寫成(int)((p)[n]),資料型別為整型int ,陣列內的元素也是整型量,可以預設為這個陣列名為

p,陣列內有n個整型元素,但是p與p的關係式指向的關係,即p指向p,根據陣列的知識可知,*p就是陣列首元素的地址,所以p在這裡也是雙重指標,這裡可以將p認為是二重陣列的陣列名;
舉個例子:

#include <stdio.h>

void main()
{
	int a[][4] = {{1,2,3,4},{12,23,34,45},{1234,23456,34567}};
	int (*p)[4] = a;
	/* 這句可以寫成:
	int (*p)[4];
	p = a;
	*/
//1	
	printf("%d\n",a);
	printf("%d\n",p);
//2
	printf("\n");
	printf("%d\n",*a);
	printf("%d\n",*p);
//3
	printf("\n");
	printf("%d\n",a[0]);
	printf("%d\n",p[0]);   //注意:*a=a[0],*p=p[0];
//4
	printf("\n");
	printf("%d\n",&a[0][0]);
	printf("%d\n",&p[0][0]);
//5
	printf("\n");
	printf("%d\n",**a);
	printf("%d\n",**p);
}

執行結果:
在這裡插入圖片描述
分析:

  1. 從1,2,3,4可以看出來,(值)a=p=*a=*p=&a[0][0]=&p[0][0] ;它們都代表地址,而且是二維陣列a的首元素的首元素的地址;這裡就將p與二維陣列連線了起來;

所以:int (p)[n] 就是一個陣列指標,資料型別為int ()[n];陣列元素為陣列;