指针数组和数组指针的区别

指针数组和数组指针区别

一、概念

1、指针数组

指针数组,指针这个词是修饰数组的,所以它本质是一个数组,是个数组元素类型为指针的一个数组。
定义形式:*p[n]

2、数组指针

数组指针,数组这个词是修饰指针的,所以它本质是一个指针,是个指向数组的一个指针。
定义形式:(*p)[n]

3、*p[] 和 (*p)[] 的区别

首先明确一个优先级顺序:( ) = [ ] > * ,( ) 和 [ ] 是属于同一优先级,它们结合方向是从左到右的

*p[n] ,[ ] 优先级高于 * ,所以 p 先和 [n] 结合即 p[n] ,p 表示一个数组,然后这个数组在和 * 结合,即表示数组元素的类型是指针,所以 *p[n] 表示指针数组

(*p)[n] ,( ) 和 [ ] 的优先级一样,但是它们是从左到右结合,所以 ( ) 优于 [ ] ,所以 p 先和 * 结合,即 *p ,p 表示一个指针,然后这个指针和 [n] 结合,即指向一个长度为 n 的一个数组,所以 (*p)[n] 表示数组指针
(int (*p)[n] 可以认为是 int [n] *p ,int [n] 为长度为 n 的数组,然后指针 p 指向这个数组。)

int *p[4];	//指针数组,一个长度为 4 的数组,数组元素为指向int类型的指针
int (*p)[4];//数组指针,一个指向数组长度为 4 的指针

二、指针数组和数组指针在使用时的详解

首先明确一个概念,对数组的首地址进行 解引用 表示的是数组的首元素地址
(数组首地址和首元素地址可看这篇文章:数组名+1和&数组名+1的区别

int num[12] = {1,2,3,4,5,6,7,8,9,10,11,12};
printf("%d %d\n",*&num,**&num);
输出 6422184 1

&num 表示的是 num 这个数组的数组首地址,*&num 表示的 num 这个数组的首元素地址,所以 **&num 即为数组首元素的值。

1、指针数组
int *p[3];
int num1[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
for (int i = 0; i < 3; i++)
	p[i] = num1[i]; 
//num1[0] num1[1] num1[2] 分别表示三个第二维数组的数组名
//它们分别指向各自的数组的首元素地址,相当于一个指针
//所以进行 p[i] = num1[i] 赋值操作

//输出各元素值
for (int i = 0; i < 3; i++)
{
	for (int j = 0; j < 4; j++)
		printf("%-2d ",*(p[i]+j));
		//p[i] 表示指针,所以*p[i]表示取内容 
	printf("\n");
/********输出**********
1  2  3  4
5  6  7  8
9 10 11 12
***********************/
}
for (int i = 0; i < 3; i++)
	p[i] = num1[i];

num1[0]、num1[1]、num1[2] 分别表示三个第二维数组的数组名,它们分别指向各自的数组的首元素地址,相当于一个指针,所以进行 p[i] = num1[i] 赋值操作。

2、数组指针

int (*p)[n],数组指针,一个指向元素为整型、长度为 n 的一维数组的指针。实际上这个指针 p 指向的是数组的首地址(区别于首元素地址),对 p 解引用表示的是首元素的地址,再次解引用(对 p 两次解引用)表示数组的元素值,所以 数组指针 类似于一个二级指针。

1)在一维数组中

//在一维数组中
int (*p1)[12];
int num2_1[12] = {1,2,3,4,5,6,7,8,9,10,11,12};
p1 = &num2_1;
for (int i = 0; i < 12; i++)
	printf("%d ",*(*p1+i));
	//两次解引用输出元素值
//输出 1 2 3 4 5 6 7 8 9 10 11 12

num2_1 是一维数组的数组名,相当于一级指针;p1 是个数组指针相当于二级指针,所以在赋值时 取 num2_1 的地址 赋值 给 p1 。

2)在二维数组中

//在二维数组中 
int (*p2)[4];
int num2_2[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
p2 = num2_2; // p2等价于 &num2_2[0] 即为第二维第一个数组的首地址
		  //所以 p2+1 为 &num2_2[1] 跨度为 4*(sizeof(int)) 
for (int i = 0; i < 3; i++, p2++) 
{
	for (int i = 0; i < 4; i++)
	printf("%-2d ",*(*p2+i)); 
	// p2 表示num2_2[0]的数组首地址,
	// p2 等价于 &num2_2[0](数组首地址)
	//所以 *p2 等价于 num2_2[0](数组首元素的地址)
	//所以 **p2 等价于 num2_2[0][0] 即元素值
	printf("\n");
}
/********输出**********
1  2  3  4
5  6  7  8
9 10 11 12
***********************/				 		   				

二维数组的数组名相当于二级指针,所以在赋指是直接赋值就行了,p2 = num2_2。
注意和一维数组的赋值的区别。

p1 = &num2_1;//一维数组的赋值
p2 = num2_2; //二维数组的赋值
  • 17
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值