不使用第三个变量交换两个变量的值,不同编译器的不同结果

6 篇文章 0 订阅

0 提出问题

0.1 一个有趣的问题

这个问题就是: 怎样不使用第三个变量交换两个变量的值?
一般我们交换两个变量的值,一般使用一个中间变量,例如下面的例子:

int a = 1, b =2;
//交换的方法,借用第三个变量temp
int temp = 0;
temp = a;
a = b;
b = temp;

这个应该是都明白的方法了。
但是这个方法借用了第三个变量。
怎样能够做到不使用第三个变量就能够交换这两个变量呢?

0.2 不使用第三个变量交换两个变量的方法

0.2.1 第1种办法

    public void change1(int a, int b){
        System.out.println(“change1交换之前\ta:”+a+”\tb:”+b);
        a = a + b – (b = a);
        System.out.println(“change1交换之后\ta:”+a+”\tb:”+b);
    }

0.2.2 第2种办法

    public void change2(int a, int b){
        System.out.println(“change2交换之前\ta:”+a+”\tb:”+b);
        b = a + (a = b)*0;
        System.out.println(“change2交换之后\ta:”+a+”\tb:”+b);
    }

0.2.3 第3种办法

    public void change3(int a, int b){
        System.out.println(“change3交换之前\ta:”+a+”\tb:”+b);
        a = a + b;
        b = a – b;
        a = a – b;
        System.out.println(“change3交换之后\ta:”+a+”\tb:”+b);
    }

0.2.4 第4种办法

    public void change4(int a, int b){
        System.out.println(“change4交换之前\ta:”+a+”\tb:”+b);
        a = a * b;
        b = a / b;
        a = a / b;
        System.out.println(“change4交换之后\ta:”+a+”\tb:”+b);
    }

0.2.5 第5种办法

    public void change5(int a, int b){
        System.out.println(“change5E交换之前\ta:”+a+”\tb:”+b);
        a = a^b;
        b = a^b;
        a = a^b;
        System.out.println(“change5E交换之后\ta:”+a+”\tb:”+b);
    }

0.3 上面的方法小结

确实,这些方法我看过之后都觉得挺好的,我觉的大开眼界,决定以后用到的时候试试看。
并且上面的方法都是使用Java语言写的,这个一般人都能够看出来。

1 蛋疼问题的出现

由于上面的方法感觉不错,因此在一次做一个小的程序实验的时候就很想试试。
这个次测试的语言是C++语言的,软件的环境是Qt5.7.1,使用的编译器是MinGW
在程序中,我写了如下的语句:

val1 = val0 + (val0 = val1) - val1;

于是,发生的一个很蛋疼的问题,它们居然没有交换成功。
在我的感觉里面,这个应该可以啊,并且我觉得这样写没有问题。
于是,我在网上找到了0.2.1小结里面写的那个,将代码换成下面的样子:

val1 = val0 + val1 - (val0 = val1);

其实,我就是觉得不甘心,就那么一测试,居然可以,所以测底觉得蛋疼。
于是,我写了下面的笔记:
这里写图片描述
在我的感知里面,它们执行的结果怎么都应该是一样的,总觉的上面的东西有问题。
于是,我就开始了下面的测试

1.1 我的源程序

下面是我的测试源程序:

#include <iostream>

void test1();
void test2();
int main()
{
    test1();
    std::cout << "--------------" << std::endl;
    test2();
    return 0;
}

void test1()
{
    int val0 = 4, val1 = 9;
    std::cout << " 测试:" << "val1 = val0 + (val0 = val1) - val1" << std::endl;
    std::cout << " 初始化的值:" << std::endl;
    std::cout << "val0 = " << val0 << std::endl;
    std::cout << "val1 = " << val1 << std::endl;
    val1 = val0 + (val0 = val1) - val1;
    std::cout << " 转换后的值:" << std::endl;
    std::cout << "val0 = " << val0 << std::endl;
    std::cout << "val1 = " << val1 << std::endl;
}

void test2()
{
    int val0 = 4, val1 = 9;
    std::cout << " 测试:" << "val1 = val0 + val1 - (val0 = val1)" << std::endl;
    std::cout << " 初始化的值:" << std::endl;
    std::cout << "val0 = " << val0 << std::endl;
    std::cout << "val1 = " << val1 << std::endl;
    val1 = val0 + val1 - (val0 = val1);
    std::cout << " 转换后的值:" << std::endl;
    std::cout << "val0 = " << val0 << std::endl;
    std::cout << "val1 = " << val1 << std::endl;
}

1.2 Qt5.7.1+MinGW 测试的结果

测试的结果如下:

娴嬭瘯锛歷al1 = val0 + (val0 = val1) - val1
鍒濆鍖栫殑鍊硷細
val0 = 4
val1 = 9
杞崲鍚庣殑鍊硷細
val0 = 9
val1 = 9
--------------
娴嬭瘯锛歷al1 = val0 + val1 - (val0 = val1)
鍒濆鍖栫殑鍊硷細
val0 = 4
val1 = 9
杞崲鍚庣殑鍊硷細
val0 = 9
val1 = 4

没错,你看的没错,执行的结果中,中文就是乱码。
但是可以方便看出执行的结果:

有一个交换成功了
有一个交换失败了

1.3 Visual Studio 2015执行的结果

如图所示:
这里写图片描述
出任所料,执行的结果是:

全部执行失败

1.4 Qt5.7.1 + Visual Studio 2015执行结果

测试:val1 = val0 + (val0 = val1) - val1
初始化的值:
val0 = 4
val1 = 9
转换后的值:
val0 = 9
val1 = 9
--------------
测试:val1 = val0 + val1 - (val0 = val1)
初始化的值:
val0 = 4
val1 = 9
转换后的值:
val0 = 9
val1 = 9

这个直接使用的是1.2里面的源代码重新编译的,但是由于里面有中文,就直接崩溃了,里面显示缺少分号什么的问题一大堆,直接将一份好的代码复制进去,就基本OK了,编译的结果如上。
这个结果是跟1.3的结果是一样的:

两个都执行失败

1.5 Java、Android和IOS里面执行的结果

将他们写在一起的主要原因是:
它们执行的效果一样。
执行的结果是:

全部可以执行

1.6 原因猜测

很明显,跟使用什么的语言没有关系
最多,就是使用的编译器不一样导致的

2 小结

我只能有如下的感叹了:
1 程序要写的尽量明白
2 程序要写的尽量明白,别老简写
3 程序要写的尽量明白,写的人容易看懂,给写编译器的人就越少可能产生不同

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值