利用指针在子函数中交换两个整数的值

利用指针在子函数中交换两个整数的值

在子函数中,系统会把主函数传递进来的参数进行拷贝,并对拷贝的数据进行处理,这样就能在得到结果的同时不改变主函数中原本的值。那么假如我们想要在子函数中,改变主函数中的值要怎么做呢?这时,就需要指针了。

情况一

假如我们不使用指针,只用交换的普通三段式,结果会怎么样呢?
代码如下:

#include<stdio.h>
void Swap(int a,int b)
{
	int tmp=a;
	a=b;
	b=tmp;
}
int main()
{
	int a=10;
	int b=20;
	Swap(a,b);
	printf("%d %d",a,b);
	return 0;
}

而其运行结果如下:
在这里插入图片描述

虽然在子函数中变量的名称和在主函数中一致,但其实主函数中的a和子函数中的a并不是同一个变量,同理,主函数中的b和子函数中的b也不是同一个变量。
这串代码会在子函数中创建两个分别名为a,b的变量,然后根据参数传递,a的值就等于主函数中的a的值10,b的值就等于主函数中b的值20。接着,借助临时变量tmp,将子函数中的a,b的值进行交换。最终主函数中的a,b分别为10,20;子函数中的a,b的值分别为20,10。所以,当我们在主函数中依次输出a,b时,其最终结果为10,20。

情况二

下面我们就加上指针,当参数传递变成指针形式,又会发生什么呢?
代码如下:

#include<stdio.h>
void Swap(int *a,int *b)
{
	int *tmp=a;
	a = b;
	b= tmp;
}
int main()
{
	int a=10;
	int b=20;
	Swap(&a,&b);
	printf("%d %d",a,b);
	return 0;
}

在这种写法中,我们更能看到主函数中的a和子函数中的a并不是同一个变量。在主函数中,a是整型变量,而在子函数中,a是一个指向整型的指针。
这串代码的运行结果如下:
在这里插入图片描述
其作用是,在子函数中创建两个指针变量a,b,分别指向主函数中的整型变量a,b。然后在子函数中创建临时指针变量tmp,交换子函数中指针变量a,b中存储的地址,最终子函数中的指针变量a指向了主函数中的整型变量b,子函数中的指针变量b指向了主函数中的整型变量a。最终在主函数中输出a,b的值,依旧是10,20。
需要注意的是,在函数Swap中,

int *tmp=a;

语句等同于

int *tmp;
tmp=a;

情况三

有的人可能会说,既然在子函数中改变主函数中的变量的值需要指针,前面都已经应用指针了,为什么还不能交换a,b的值呢?
其实,仅仅让指针从子函数中指向主函数还不能达到目的,我们还缺少一个步骤。就是在子函数中对相应的指针进行解引用,从而真正触碰到主函数中的变量值。
而在对指针进行解引用的过程中,会经常出现一个错误现象,代码如下:

#include<stdio.h>
void Swap(int *a,int *b)
{
	int *tmp;
	*tmp = *a;//错误
	*a = *b;
	*b = *tmp;
}
int main()
{
	int a=10;
	int b=20;
	Swap(&a,&b);
	printf("%d %d",a,b);
	return 0;
}

从逻辑上来讲,这串代码确实应该能够交换a,b的值,但是,从语法上来看,这串代码涉及到了指针中很危险的一个实例,野指针。
野指针,也称为悬挂指针。其特征是定义后的新指针还未被初始化。这种指针的特点是谁也不知道这个指针存放的地址变量存在还是不存在,换句话说,即使连代码书写者也不知道这种指针指向哪里,一旦对其进行解引用,将相应的值进行修改,而我们又不知道修改的值的初值是什么,无法还原,很可能就会对计算机产生不可挽回的损害,所以,c语言会在对野指针进行解引用时将程序崩溃。
所以,这串代码最终会在图示标记处崩溃,结果如下;
在这里插入图片描述
错误提示:The variable ‘tmp’ is being used without being initialized.
变量tmp还未进行初始化就被使用。

情况四

既然知道了问题的原因,那么我们就认为给tmp赋一个值,使其不再是野指针,改正后的代码如下:

#include<stdio.h>
void Swap(int *a,int *b)
{
	int c;
	int *tmp=&c;
	*tmp=*a;
	*a = *b;
	*b = *tmp;
}
int main()
{
	int a=10;
	int b=20;
	Swap(&a,&b);
	printf("%d %d",a,b);
	return 0;
}

容易看到,这种使用方法使得我们多定义了一个临时变量c,无实际意义,所以,结合前面的经验,将代码改进,我们可以选择将tmp定义成为整型变量而不是指针变量,改进后的代码如下:

#include<stdio.h>
void Swap(int *a,int *b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
int main()
{
	int a=10;
	int b=20;
	Swap(&a,&b);
	printf("%d %d",a,b);
	return 0;
}

该代码的作用是,在子函数中利用指针变量a,b访问主函数中的变量a,b,利用临时变量tmp,对指针变量a,b解引用,从而交换主函数中a,b的值。
其运行结果如下:
在这里插入图片描述
这就是我们最终得到的答案。
各位看官,都看懂了吗?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值