交换变量的三种方法

本文介绍了三种交换两个变量值的方法:使用临时变量的三变量法,无需额外变量的加减法和位运算法(异或)。尽管后两者看似简洁,但受限于数据类型,实际应用中通常首选三变量法,以确保通用性和易理解性。
摘要由CSDN通过智能技术生成

交换两个变量的值,有三种方法。

一、三变量法:最经典的方法(推荐方法):

我们说变量就像容器,变换两个变量的值可以比作变换两个容器中装的东西。比如将一瓶酱油和一瓶醋交换,这时便需借助一个空瓶子进行交换。先将酱油倒入空瓶,再将醋倒入酱油瓶,最后将空瓶中的酱油倒入醋瓶。

交换两个变量也是一样,需经增加一个空瓶,我们叫它“临时变量”,所以三变量法也叫“临时变量法”。

#include<stdio.h>

int main()

{

int a, b, t;

scanf("%d%d", &a, &b);

t = a; //t为临时变量

a = b;

b = t;

printf("%d %d\n", a, b);

return 0;

}

二、加减法:不增加变量,通过加减运算交换变量。

#include<stdio.h>

int main()

{

int a, b;

scanf("%d%d", &a, &b);

a = a + b;

b = a - b;

a = a - b;

printf("%d %d\n", a, b);

return 0;

}

可以通过手工模拟理解这段程序,看看每条语句执行后的情况。

在顺序结构程序中,程序一条一条依次执行。为了避免值和变量名混淆,假定用户输入的是a0和b0,因此scanf语句执行完后a=a0,b=b0。

执行完a=a+b后:a=a0+b0,b=b0。

执行完b=a-b后:a=a0+b0,b=a0。

执行完a=a-b后:a=b0,b=a0。

加减法还有另外一种形式,就是先用减法,道理是一样的。

#include<stdio.h>

int main()

{

    int a, b;

    scanf("%d%d", &a, &b);

    a = a - b;

    b = a + b;

    a = b - a;

    printf("%d %d\n", a, b);

    return 0;

}

三、位运算法:不增加变量,用异或运算交换变量

#include<stdio.h>

int main() {

int a, b;

scanf("%d%d", &a, &b);

a = a ^ b; 

b = a ^ b; 

a = a ^ b;

printf("%d %d\n", a, b);

return 0;

}

异或运算是一种二进制运算,其运算规则为:对于每一位,如果两个相应的二进制位相同,则结果为0;如果两个相应的二进制位不同,则结果为1(相同为0,相异为1)。

比如两个二进制数a0=0011,b0=0101,则a0^b0=0110。

a00011
b00101
a0^b00110

这个运算规则很简单,但却有大用处。因为可以从中总结出一条运算规律:

a0^( a0^b0)=b0

b0^( a0^b0)=a0

这个规律不是很好理解,可以简单这样想:

假设面对面站着A、B两排人数一样的男女,现在要记录面对面站着的两个人性别有无差别,有差别记为“有”,无差别记为“无”:

A排
B排
差别

你可能已经发现,这个表和上面的表很相以,只要把男改为1,女改为0,有改为1,无改为0。

现在如果有人告诉你A排的男女排列情况、A排与B排的差别,你一定能得出B排的男女排列,它的推理逻辑是这样的:

男、有差别=女

男、无差别=男

女、有差别=男

女、无差别=女

这就是a0^( a0^b0)=b0之所以能成立的根本逻辑。

只不过,通过巧妙地把男、有差别设为数字1,把女、无差别设为数字0,再引入相同为0相异为1的异或运算符^,把上面的逻辑转换成了数学表达式:

男、有差别=女:1^1=0

男、无差别=男:1^0=1

女、有差别=男:0^1=1

女、无差别=女:0^0=0

所以,可以简单将a ^ b理解为a与b的差别,然后有:

a^差别=b,b^差别=a。

这样就能很好理解了。

根据这个规律就可以实现交换变量。

同样假定用户输入的是a0和b0,因此scanf语句执行完后a=a0,b=b0。

执行完a = a ^ b后:a=a0^b0,b=b0。

执行完b = a ^ b后:a= a0^b0,b=a ^ b=( a0^b0) ^b0=a0。

执行完a = a ^ b后:a= a ^ b=( a0^b0) ^a0=b0,b=a0。

这三行交换代码在形式上堪称简洁优美,等号左边依次为a、b、a,像是一道轮回,等号右边居然都是同一个表达式a ^ b,不由让人感叹鬼斧神工。

这三板斧其实还可以进一步简写成a^=b^=a^=b,但不建议使用。因为用异或来交换变量本来就很难理解了,再搞成这种美不胜收的形式,简真让人不敢直视。这种简写其实是一种组合赋值运算,因为赋值运算符是从右向左计算的,所以这一连串表达式可以解析为:

a^=b; //即a = a ^ b;

b^=a; //即b = a ^ b;

a^=b; //即a = a ^ b;

可见,它和前面的代码是完全一样的。

还有一点需要注意的是:a^=b^=a^=b的非简写表达式其实是这样的:

①a=a^(b=b^(a=a^b))

而不是这样的:

②a=a^b=b^a=a^b

一定要理解这其中括号的作用,只有①才是与原式完全一一对应的。

②式本身就存在语法错误,如果要计算,还是从右向左计算,第一个式子要解析成:b^a=a^b。这就是出错的原因:赋值只可以赋给变量,不能赋给一个表达式。

总结:

虽然第二、三种方法看起来很好(少用一个变量),但实际上很少使用,因为它的适用范围很窄:第二种只有定义了加减法的数据类型才能采用,第三种只适用于整型,所以掌握这样的技巧只为提高编程能力,不推荐将其用于变量交换。三变量法已经足够好,它适用于任何数据类型。

  • 60
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

金创想

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值