转载:C语言实现一级二级多级指针

题目

指针

转载实践来自悄然拔尖

关于指针,在《c和指针》上是这样形容的,指针就是地址的另外一个叫法。

所以我们要明白,指针和指针变量的区别,指针就是地址,指针变量是存放指针的变量,即指针变量存放的是地址,我们通过间接访问符可以得到该地址的内容。

但是,在一般情况下,我们都把指针变量说成指针这样的简称。例如:

void (*fuc)(int a);

我们会说fuc是一个指针,指向一个参数为int返回值为void的函数。

这个时候我们并不它称作指针变量,而笼统地称为指针,因为我们使用指针的情况下,大多是在操作指针变量,但是,在某些情况下,需要精确表述时,应该明白,指针变量是存放地址(指针)的,指针就是一个地址。后面所说的指针,不特殊说明,都指指针变量,因为指针和指针变量大部分时候我们不是去区分它的文字定义,而是怎么去使用它。

比如,

char *p=NULL;

我们都说p是一个指针,其实严格来说这个p是指针变量。因为定义一个指针类型的变量,必然在内存中开辟了空间,就是指针变量了,但已经被大家都这样叫指针了,所以,虽然我们这样叫着,但具体含义还是要清楚的。我们使用赋值方式给一个“指针”的时候,这个指针一定已经是指针变量了,因为地址不能做左值,地址对应的内存空间才可以。不过始终得有个约定吧,所以就先统称指针了。

指针就是为间接赋值或者说间接改变某些东西存在的。

#include <stdio.h>

int main()
{
	// 每一层* 就相当于开一次锁,逐层深入进行开门,取出对应地址的值
	int a = 10;
	int *p1 = NULL;
	int **p2 = NULL;

	// 直接修改方式
	a = 20;
	printf("a: %d\n", a);
	// 一级间接修改
	p1 = &a;
	*p1 = 30;
	printf("a: %d\n", a);
	// 二级间接修改
	p2 = &p1;
	**p2 = 40;
	printf("a: %d\n", a);
	return 0;
}

可能在这里你会觉得,既然一级指针就已经能够更改一个地址的变量了,为什么还要二级指针或者多级指针呢?

一级指针用普通变量的地址去接,二级指针用一级指针的地址去接,N级指针用N-1级指针的地址去接。

我们在一个程序中已经使用了一级指针了,如果我们想修改这个一级指针或者这个一级指针指向的内容,就会使用到二级指针了,但是,为了代码的可读性,最好用二级以下的指针解决。

指针变量需要指向一个内存空间,内存空间相当于门牌号,而对一个指针解引用(*),相当于间接访问这个指针变量中存储的地址里面对应的内容,(*)相当于一把钥匙打开了房门。

/*
指针变量需要指向一个内存空间,内存空间相当于门牌号,
而对一个指针解引用(*),相当于间接访问这个指针变量中存储的地址里面对应的内容,
(*)相当于一把钥匙打开了房门。
*/
#include <stdio.h>

int main()
{
	int a = 100;
	int *p1;
	int **p2;

	p1 = &a;  // 随便给的地址数据
	printf("0x%x\n", p1);

	p2 = &p1; 	// 二级指针需要一级指针的地址初始化
				// 其实任意地址都可以,不过会有警告
	/* 如果直接通过这种方式进行赋值,那么会提示告警,无法实现int* 类型数据向int**类型数据的转换
	int a = 10;
	p2 = &a; 
	*/
	
	/* 以下方式可以完成赋值
	int b = 4000;
	*p2 = &b;
	*/
	*p2 = (int*)123;  // 使用int* 将int行数据6422020强制转换为int 指针类型数据,否则无法完成赋值
	printf("p1: %d\n", p1);
	
	return 0;
}
示例体现二级指针用法
# include <stdio.h>

void one_pointer(int *mp)
{
	*mp = 30;
}
/*
要改变p的值,和普通变量一样,可以直接修改,也可以间接修改
和普通变量a有需要间接修改的需求一样,指针变量p也有这样的需求
此时就需要使用二级指针
*/
void two_pointer(int **mmp)
{
	/* mmp是二级指针,不管是多少级,始终记住,加一个(*)就相当于多一扇门
	   一级指针p修改普通变量a,我们通过*p = 想要修改成的目标数,这样的方式进行处理,同理
	   二级指针修改一级指针,也应该通过*mmp=想要赋值给一级指针的数, 这样的方式
	   二级指针修改一级指针执行地址的内容时,需要使用两个(*), 因为可以理解为开了两次门
	*/
	*mmp = (int *)0x100; 	// 将一级指针的值修改为100
							// 加强制类型转换是因为100是int类型常量(立即数),
							// 而*mmp希望接收的是一个int * 类型的地址
}

int main()
{
	int a = 10;
	printf("a=%d &a=%p\n", a, &a);

	int *p = &a;  	// 定义一级指针变量,并将整形变量a的地址,存入到指针变量p中
	*p = 20; 		// 对指针变量p中存放的地址,进行解析地址然后赋值为20,此时地址p中存放的值为20
	// printf("a=%d &a=%p\n", a, &a);
	printf("a=%d &p=%p\n", a, &p);  	// 变量a的地址没有变化,值更新为20,;
										// &p,标识的是指针变量p在内存中的地址

	one_pointer(p);	// p为一级指针,传递到函数中的实参为一级指针,接收的形参也为一级指针
	printf("a=%d p=%p\n", a, p);
	printf("&p=%p\n", &p);

	two_pointer(&p);  // p为二级指针,传递到函数中的实参为二级指针,接收的形参也为二级指针 
	printf("p=%p\n", p); // 此时p已经被修改
	return 0;
}
PS

主要体现一级及多级指针的使用方法!练习记录!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值