其实很简单 一个关于运算符的问题 为什么在不同的编译器下会得到不同的结果  题目是int i=3,k=0;
k=(++i)+(++i)+(++i);
System.out.println(k);
在C中是
printf("%d\n",k);同样的题目为什么会有不一样的结果,答案是
在java中的  15 
在linux 下用gcc编译是16而用turbo C 得到的结果却是 18这些编译器上存在些什么区别呢?

解决方案 »

  1.   

    表达式提取规则不同。
    在java中是顺序处理的,
    执行++i;
    将结果4拿来作为加法的第一个操作数;
    执行++i;
    将结果5拿来作为加法的第二个操作数;
    相加,得到9,作为下一步加法的第一个操作数;
    执行++i;
    将结果6拿来作为第二个操作数;
    相加,得到15.java语言规范严格规定了处理方式,所以使用不同的java编译器时得到的结果是确定的。但是C语言的规范中并没有详细规定这种情况如何处理,不同的C编译器结果可能是不同的,所以在C语言中千万不要写这样的程序。当然,虽然java中可以确定答案,但尽量也不要这么写,因为看起来累。
      

  2.   

    java这样问还有情可原,虽然无聊。
    c这样问就是典型找抽了。
      

  3.   

    跟语言规范中的规定相关。如果语言规范对某些行为没有严格定义,那么编译器的实现就可以自行发挥。 Java的语言规范明确规定了表达式的求值顺序是从左向右(15.7小节)。楼主的代码里,每个++i都是双目运算符+的操作数根据从左向右的求值顺序,要求第一个+的值,就必须先求第一个++i的值,结果是3+1;然后求第一个+右边的操作数,是“(++i) + (++i)”,于是重复求值过程,第二个++i就是4 + 1,第三个++i就是5 + 1,全部加起来就是15。由于语言规范做了严格的规定,所有符合规范的Java编译器都应该编译出同样效果的程序。 C语言则没有规定表达式的求值顺序,也没有严格规定“一个完整表达式里副作用的顺序”。C99语言规范写明++E完全等价于(E+=1)(6.5.3.1小节)。赋值表达式的规定在6.5.16,说赋值表达式的副作用应该发生在前一个和后一个顺序点之间,并且求值顺序未定义。关于顺序点的规定在附录C,楼主代码中, 
    C代码 
    int i = 3, k = 0;  int i = 3, k = 0;
    这句有两个顺序点,分别是i = 3后的逗号和k = 0后的分号处。 
    C代码 
    k = (++i) + (++i) + (++i);  k = (++i) + (++i) + (++i);
    这整个是一个“表达式语句”,只有一个顺序点,就在末尾的分号处。 
    根据C99的规定,++i的副作用发生在k=0;之后和(++i);之间的任意位置都可以。所以不同的编译器就采取了不同的实现方式,GCC对该表达式的理解是: 
    C代码 
    i += 1;   
    i += 1;   
    temp = i + i;   
    i += 1;   
    temp += i;   
    k = temp;  i += 1;
    i += 1;
    temp = i + i;
    i += 1;
    temp += i;
    k = temp;
    Turbo C和VC9的理解是: 
    C代码 
    i += 1;   
    i += 1;   
    i += 1;   
    temp = i + i;   
    temp += 1;   
    k = temp;  i += 1;
    i += 1;
    i += 1;
    temp = i + i;
    temp += i;
    k = temp;
    而这都是C语言规范所允许的。之所以定义得比较宽松,是为了让编译器实现者能更自由的选用优化方式来产生高效的代码。 无论如何,良好的代码风格中,一个完整的表达式里最好不要有多余一个副作用,不然代码就会难以阅读。在C、C++等没有定义求值顺序的语言中,依赖求值顺序去求表达式的值更是很危险的作法,因为编译器的不同版本间都有可能改变求值顺序,更不提不同编译器间的不同实现。不过了解一下为什么会出现差异还是有好处的…… 
    遇到问题先看规范,没错的。
      

  4.   

    跟语言规范有关。
    1.在java中 ++ 运算符  优先级高于 + 运算符。
    楼主的 整个表达式 从左到右执行运算,k=(++i)+(++i)+(++i); =》k=(3+1)+(3+1+1)+(3+1+1+1)=15
    java虚拟机都是按照这个规则执行运算的,所以得到的结果是相同的。2.C语言则没有规定表达式的求值顺序,也没有严格规定“一个完整表达式里副作用的顺序”。  不同的编译器实现会有不同的结果,是可以理解的。