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

来源:互联网 发布:淘宝网店怎么寻找货源 编辑:程序博客网 时间:2024/05/16 15:36

0 提出问题

0.1 一个有趣的问题

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

int a = 1, b =2;//交换的方法,借用第三个变量tempint 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 = 4val1 = 9杞崲鍚庣殑鍊硷細val0 = 9val1 = 9--------------娴嬭瘯锛歷al1 = val0 + val1 - (val0 = val1)鍒濆鍖栫殑鍊硷細val0 = 4val1 = 9杞崲鍚庣殑鍊硷細val0 = 9val1 = 4

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

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

1.3 Visual Studio 2015执行的结果

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

全部执行失败

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

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

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

两个都执行失败

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

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

全部可以执行

1.6 原因猜测

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

2 小结

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

0 0
原创粉丝点击