以前自作聪明以为自增在java和c中是一样的,原来错了
原文链接:http://blog.csdn.net/maggiedorami/article/details/7986098
我们来看这样一段程序:
- public static void main(String[] args){
- int i, sum1, sum2;
- i=0;
- sum1 = (i++)+(i++);
- System.out.println("sum1="+sum1);
- i = 0;
- sum2 = (++i)+(++i);
- System.out.println("sum2="+sum2);
- }
它的运行结果是:
- sum1=1
- sum2=3
而我用c语言编写相同逻辑的代码得到的却是不同的结果:
- void main()
- {
- int i,sum1,sum2;
- i=0;
- sum1=(i++)+(i++);
- printf("sum1=%d\n",sum1);
- i=0;
- sum2=(++i)+(++i);
- printf("sum2=%d\n",sum2);
- getchar();
- }
它的运行结果是:
- sum1=0
- sum2=4
这种不同是因为在c语言中,每个变量在它的生命周期内的每个时间点都只能有一个唯一的值。因此变量在每一次自增运算时,变量所对应内存区域的内容就被重写了。
而在java中,执行sum1=(i++)+(i++);创建了2个临时的整型变量对象,对来存储每次自增运算的结果。
java采用了这种中间缓存变量的机制。
再看程序员面试宝典中一个很经典的例子:
- public static void main(String[] args){
- int j = 0;
- for(int i = 0; i < 100; i++)
- j = j++;
- System.out.println(j);
- }
对java来说,j的输出值是0。
(下面这段代码的解释,我还是不明白,望网友帮忙解释)
因为java的中间缓存变量机制使j=j++语句看以分解成如下操作:
- temp = j;
- j = j + 1;
- j = temp;
个人觉得这样使用自增并不好,应该在复杂语句中避免使用后置的自增(自减)。
另外,值得注意的是某些采用了中间缓存变量机制的语言,输出并不一定是0。比如C++在对一些基本类型以及指针类型进行后置自增操作时,编译器将省去中间缓存变量的操作。
PS:找到另外一个解释了,并做了验算
在java中计算过程中,使用了Java中间变量缓存机制,执行自增运算时,会为每一个自增操作分配一个临时变量。
如果是前缀加(++i),就会“先自加1后赋值(给临时变量)”;
如果是后缀加(i++),就会“先赋值(给临时变量)后自加1”。
运算最终使用的,并不是变量本身,而是被赋了值的临时变量。
j = j++;
等同于:
int temp = j;
j = j + 1;
j = temp;
j = ++j;
等同于:
j = j + 1;
int temp = j;
j = temp;
package com.job.written.iii;
public class Test {
public static void main(String[] args) {
int i = 0, j = 0, k = 0;
for (i = 0; i < 100; i++) {
j = j++;
k = ++k;
}
System.out.println("j = j++ is " + j);
System.out.println("k = ++k is " + k);
}
}
cout>>
j = j++ is 0
k = ++k is 100