为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 下面这段代码 C++ 和 Java 在 上不同?i+=i-=i*=i

为什么 下面这段代码 C++ 和 Java 在 上不同?i+=i-=i*=i

扬帆大鱼 2018-11-09 11:11:01
#include<stdio.h>//在C++中的结果int Change(int i);main(){int i=7;int j=Change(i);printf("%d ,  %d",i,j);} int Change(int i){return i+=i-=i*=i;} /*,  0-----------------------------------------------Process returned: 0 (0x0)Execution time: 14 msMaximum memory use: 407 KB-----------------------------------------------Press any key to continue . . .*///在 Java中的运行结果/** * Created by Xi Yin on 2016/9/8. */public class TestPlusPlus {public static void main(String[] args){int i=6;        System.out.println(i);int j=Change(i);        System.out.println("Value1: "+i+" Value2: "+j);    }public static int Change(int k){return k+=k-=k*=k;    }}/**Value1: 6 Value2: -24Process finished with exit code 0* */
查看完整描述

4 回答

?
onemoo

TA贡献883条经验 获得超454个赞

关于 i+=i-=i*=i

其中运算符的优先级和结合性在 C++ 和 Java 中是一样的,所以和这个没关系。

C++ 和 Java 在这里的区别是对具体执行过程的规定不同!  准确地说,Java 对此有明确的规定,这个表达式能得到确切的结果;而在 C++ 中这个表达式的行为是“未定义”的。


C++ 标准对于运算符表达式的执行过程有一个复杂的“序列点”(或新的“先序”)规则。而这些规则对于一些运算符执行的某些过程没有作出明确的规定,实际代码可以以任意可能的方式执行,这就是 C++ 的所谓“未定义行为”。

你给出的这个表达式中就正好涉及这点。 关于这个复杂的规则的解说请参考我之前的回答:http://www.imooc.com/qadetail/87888

你这里连续使用的复合赋值运算符也是有“副作用”的,而这些副作用的发生顺序也是未定义的,所以,在 C++ 中这样的代码可以得到各种结果。你不应该在 C++ 中这样写,这算是错误的代码。

顺便说下,C++ 这样做并不是不严谨,这是为适配不同底层硬件和提高执行效率而有意为之。这是 C++ 的灵活性之一,也是它复杂(有坑)的地方。程序员必须很熟悉这些语法细节才能写出正确的代码。


Java 就比较简单了,它对此有明确的规定,所以最后会得到确定的结果。详细解释请参考我在这里的回答:https://www.imooc.com/wenda/detail/387946


查看完整回答
反对 回复 2018-11-16
?
函数式编程

TA贡献1807条经验 获得超9个赞

两门不同的语言,语法细节上的不同,很奇怪吗?


查看完整回答
反对 回复 2018-11-14
?
郎朗坤

TA贡献1921条经验 获得超9个赞

那就是符号优先级的问题呗,这种代码还是少写。。。毕竟,编程不是炫技。。。

两种都是从后往前运算,但是运算过程中,Java的K的值一直没变,所以Java等同于这样:

k=6+6-6*6;最后是-24;

而C++是每次运算完以后,i就变了,所以是:

i=i*i;这时候i是49;

i=i-i;这时候等于49-49,等于0;

i=i+i;这时候等于0+0,等于0;最后等于0


查看完整回答
反对 回复 2018-11-14
  • 4 回答
  • 1 关注
  • 1015 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信