您现在的位置是:首页 > 文章详情

由变量值交换编程题想到的(C++与Java机制的不同)

日期:2018-10-29点击:281

今天网上看到一个老套的编程题,就是“不用第三个变量进行两个变量的值交换”。是一个同学把java写的答案放在网上求别人解析一下。平时因为做题用的都是C++,所以好奇瞄了一眼,却发现实现方法与C++截然不同,并且,Java和C++算数表达式解析的机制也存在很大不同。好吧,我们先来看看这个例子吧。

Java实现:(本文出自:http://my.oschina.net/happyBKs/blog/416632)

public static void main(String[] args) { // TODO Auto-generated method stub int x=4; int y=5; x=y+(y=x)*0; System.out.println("x="+x+", y="+y); }

结果是:

x=5, y=4

这里我如果将表达式改为x=(y=x)*0+y; 

那么结果就是 x=4, y=4

这个例子,我相信大家能猜出其中的原因:Java在解析表达式时是从左向右执行的。

详细地说,在这个赋值语句中,先执行右边的算数表达式。执行之前x=4, y=5

算术表达式又按照从左到右的顺序执行,最左边y+先执行。这时候 x=4, y=5.没有任何变化

右边是(y=x)*0再从左向右看,首先是(y=x),执行之后,x=4, y=4. y变了!

(y=x)*0显然是0。

(y=x)*0+y则是0+y=0+4=4,赋给了赋值表达式左边的x。这时候,x=5, y=4

那么,如果在C++中的话,会怎么样呢?

代码和结果是这样的:

#include <iostream> #include <stdlib.h> /* run this program using the console pauser or add your own getch, system("pause") or input loop */ int main(int argc, char** argv) { int x=4; int y=5; //x=(y=x)*0+y; x=y+(y=x)*0; printf("x=%d, y=%d",x,y); system("pause"); return 0; }

我将x=(y=x)*0+y;和x=y+(y=x)*0;两个表达式都实验了一下。结果答案都是:

x=4,y=4

这似乎说明了,在解析算数表达式时,执行不存在像Java那样的从左到右的顺序。同时,也不是从右向左的。

C++中的执行更像是这样一种情况执行了这样一个内联函数。(我推测的)

x=4,y=5

inline void fn(int x1, int y1)

{

x1=x;

y1=y;

y=x1;

x=y1+y1*0;

}

这似乎有点还是令人难以信服。那么我们就彻底跑个题吧,来看两个一样的代码例子,但是分别放到了Java和C++编译和运行环境中。

在java中的一个例子:

public static void main(String[] args) { int a=1; int b,c,d; d=(b=a++)+(c=a++)+(a++); System.out.println("a="+a+", b="+b+", c="+c+", d="+d); }

运行结果:

a=4, b=1, c=2, d=6

在C++中:

#include "stdafx.h" #include <stdlib.h> int _tmain(int argc, _TCHAR* argv[]) { int a=1; int b,c,d; d=(b=a++)+(c=a++)+(a++); printf("a=%d, b=%d, c=%d, d=%d",a,b,c,d); system("pause"); return 0; }

运行结果:

105747_WWgI_1156339.png

上面的C++代码在gcc和VC下都进行了测试。

如果我把上面的例子再改一下。改为:

java:

public class TestMain { public static void main(String[] args) { int a=1; int b,c,d; d=(b=++a)+(c=++a)+(++a); System.out.println("a="+a+", b="+b+", c="+c+", d="+d); }

运行结果:

a=4, b=2, c=3, d=9

C++:

#include "stdafx.h" #include <stdlib.h> int _tmain(int argc, _TCHAR* argv[]) { int a=1; int b,c,d; d=(b=++a)+(c=++a)+(++a); printf("a=%d, b=%d, c=%d, d=%d",a,b,c,d); system("pause"); return 0; }

运行结果:

110528_qoIl_1156339.png

看到了吧。似乎这时候,C++表达式也存在了从左到右的特性。Java任然亘古不变。

是不是有点晕了,C++到底怎么了?

那么我们单独再为C++设置一个例子:这次咱们里面都是赋值。

int a=1, b=10, c=100, d=1000; d=(b=a)+(c=b)+a; printf("a=%d, b=%d, c=%d, d=%d",a,b,c,d); system("pause"); return 0; }

结果是:

111220_poN8_1156339.png

在修改个例子:如果d=(b=a)+(c=b)+++a;

运行结果是:

191759_DhcM_1156339.png

从上面的例子中已经可以看出我们之前下的结论了:Java在解析算数表达式时是从左向右执行的。C++解析算数表达式时, ++在前的因式需要在计算时就结算,并且从左向右执行。而=赋值则更像是在调用一个封装了算术表达式和赋值功能的内联函数。++在后的变量的累加操作在整个大表达式计算完成得到值之后结算。(还是整个表达式赋值之后结算?其实是等价的)

本文来自云栖社区合作伙伴“开源中国”

本文作者:HappyBKs 

原文链接

原文链接:https://yq.aliyun.com/articles/659753
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章