6.8 指针-二级指针

二级(多级)指针:保存指针变量地址的指针变量。

#include <stdio.h>
int main(){
	int data = 10;
	int *p = &data;
	printf("data的地址是:%p\n",&data);
	printf("p的地址是:%p\n");
	
	int *pp = &p;
	printf("pp的地址是:%p\n",pp);
	
	return 0;
}

结果:

data的地址是:000000000061FE14
p的地址是:00007FFB7A9DFA30
pp的地址是:000000000061FE08

   数据存储的值和地址 

data:10000000000061FE14
p:000000000061FE1400007FFB7A9DFA30
pp:00007FFB7A9DFA30000000000061FE08

也就是说二级指针的值为一级指针的地址, 是一个地址变量,虽然一级指针也能够访问指针变量的地址,但是不能**取出值,而二级指针局可以,二级指针值的访问同样和普通指针一样访问:

printf("pp访问到data:%d\n",**pp);

访问的结果:

pp访问到data:10

应用场景:

如果ppos没有赋予地址,那么它就成了野指针,如果我们根据当下函数指向数组的首地址,那么就会使数组发生改变,而我们想要的是查询数据。

什么是野指针?也就是在定义指针变量之后没有对它进行初始化,指向非法的内存地址指针叫作野指针,会出现段错误,可以通过二级指针将其本身的地址传递过来,间接修改指针变量的指向,指向数组。

#include <stdio.h>

void getscore(int pos,int (*pstu)[4],int *ppos){
	ppos = (int *)(pstu+pos);
}

int main(){
	int scores[3][4]={{11,22,33,44},{55,66,77,88},{10,20,30,40}};
	int pos;
	printf("请输入要查询学生序号数:0,1,2\n");
	
	scanf("%d",&pos);
	int *ppos;
	
	getscore(pos,scores,&ppos);
	for(int i=0;i<4;i++){
		printf("%d ",*ppos++);
	}
	return 0;
}

使用二级指针:

#include <stdio.h>

void getscore(int pos,int (*pstu)[4],int **ppos){
	*ppos = (int *)(pstu+pos);
}

int main(){
	int scores[3][4]={{11,22,33,44},{55,66,77,88},{10,20,30,40}};
	int pos;
	printf("请输入要查询学生序号数:0,1,2\n");
	
	scanf("%d",&pos);
	int *ppos;
	
	getscore(pos,scores,&ppos);
	for(int i=0;i<4;i++){
		printf("%d ",*ppos++);
	}
	return 0;
}

二级指针指向二维数组:

假设有一个二维数组,数组含三个元素,每个元素包含四个数据,转换为指针时相当于int (*p)[3],只不过不关心数组有多少个元素,关系元素包含了多少子元素。

int scores[3][4]={{11,22,33,44},
	{55,66,77,88},
	{10,20,30,40}}; //等价于int (*p)[3]

 而*scores是列地址,按理来说*p也是一个列地址,但是如果我们直接使用*p会发生段错误,因为*p是一个野指针,需要指向一个地址。

printf("*p = %p",*p);
printf("*scores = %p",*scores);

例如:

int (*p)[4] = *p;
int **p = &p;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值