其实很简单 一个关于运算符的问题 为什么在不同的编译器下会得到不同的结果 题目是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这些编译器上存在些什么区别呢?
k=(++i)+(++i)+(++i);
System.out.println(k);
在C中是
printf("%d\n",k);同样的题目为什么会有不一样的结果,答案是
在java中的 15
在linux 下用gcc编译是16而用turbo C 得到的结果却是 18这些编译器上存在些什么区别呢?
在java中是顺序处理的,
执行++i;
将结果4拿来作为加法的第一个操作数;
执行++i;
将结果5拿来作为加法的第二个操作数;
相加,得到9,作为下一步加法的第一个操作数;
执行++i;
将结果6拿来作为第二个操作数;
相加,得到15.java语言规范严格规定了处理方式,所以使用不同的java编译器时得到的结果是确定的。但是C语言的规范中并没有详细规定这种情况如何处理,不同的C编译器结果可能是不同的,所以在C语言中千万不要写这样的程序。当然,虽然java中可以确定答案,但尽量也不要这么写,因为看起来累。
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++等没有定义求值顺序的语言中,依赖求值顺序去求表达式的值更是很危险的作法,因为编译器的不同版本间都有可能改变求值顺序,更不提不同编译器间的不同实现。不过了解一下为什么会出现差异还是有好处的……
遇到问题先看规范,没错的。
1.在java中 ++ 运算符 优先级高于 + 运算符。
楼主的 整个表达式 从左到右执行运算,k=(++i)+(++i)+(++i); =》k=(3+1)+(3+1+1)+(3+1+1+1)=15
java虚拟机都是按照这个规则执行运算的,所以得到的结果是相同的。2.C语言则没有规定表达式的求值顺序,也没有严格规定“一个完整表达式里副作用的顺序”。 不同的编译器实现会有不同的结果,是可以理解的。