学习过一门计算机语言的人一定知道j=i++的运算结果,整个表达式的值为i,而i的值变为i+1;那么i=i++又是一个什么情况呢?下面分别用java和 c 两种语言来做个测试:
JAVA:
public class test
{
public static void main(String args[])
{
inti,j;
i=0;
for(j=0;j<5;j++)
{
i=i++;
System.out.println("i="+i);
}
}
}
C:
#include
main()
{
inti,j;
i=0;
for(j=0;j<5;j++)
{
i=i++;
printf("i=%d\n",i);
}
}
你也许会问,这么简单的程序会有什么问题呢?是的,如果不相信的话,你可以运行一下这两个程序,得到的结果非常让人震惊。
第一个JAVA程序得出的结果如下:
i=0
i=0
i=0
i=0
i=0
而第二个C程序得出的结果如下:
i=1
i=2
i=3
i=4
i=5
同样都是i=i++,为什么得出的结果会有这么大的差异呢?原来是在编译器上出了问题,java的编译器在遇到i++和i--的时候会重新为变量运算分配一块内存空间,以存放原始的值,而在完成了赋值运算之后,将这块内存释放掉,下面首先看一下如果是j=i++的情况:
i的原始值存放在后开辟的内存中,最后这个值将赋值给j,这样j=i++后,j就会得到i的值,而i又将自加,所以,在释放内存之后,原来存放j和i的地方将得到值将是:j(此时的值等于初始i值)和i(i自加后的值)。
明白了上面的问题,让我们接下来看看i=i++的情况:
所以这样最后一次循环内的结果仍旧是i(即0)。
而C语言中的i=i++就只是完成i++的内容,所以结论会不同。这种情况说明java和c的处理语法的机制不同,如果在程序中只输入i++就不会出现这个方面的问题,所以大家在以后的程序中如果使用到i=i++的时候要格外小心,一般只需要用i++就不会有问题了。
运行下面这段代码,其结果是什么呢?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package
com.test;
public
class
Inc {
public
static
void
main(String[] args) {
Inc inc =
new
Inc();
int
i =
0
;
inc.fermin(i);
i = i++;
System.out.println(i);
}
void
fermin(
int
i) {
i++;
}
}
|
结果是:0
上述类似代码在C/C++中运行结果是:1,这是为什么呢?
这是因为Java使用了中间缓存变量机制:
i=i++;等同于:
temp=i; (等号右边的i)
i=i+1; (等号右边的i)
i=temp; (等号左边的i)
而i=++i;则等同于:
i=i+1;
temp=i;
i=temp;
详解:
jvm里面有两个存储区,一个是暂存区(是一个堆栈,以下称为堆栈),另一个是变量区。
jvm会这样运行这条语句:
步骤1 jvm把i的值(其值是0)拷贝到临时变量区(temp=0)。
步骤2 变量区i的值加1,这时i的值是1。
步骤3 返回临时变量区(temp)的值,注意这个值是0,没修改过。
步骤4 返回值赋值给变量区的i,此时i的值被重置成0。
c/c++中没有另外设置一个临时变量或是临时空间来保存i,所有操作都是在一个内存空间中完成的,所以在c/c++中是1。
即 int i=1; i=i++ ; 结果i 值为1(为自己赋值,i不会再自增。如果为其他赋值,i会自增。)
int i=1; i=++i; 结果 i 值为 2
例子: int i=1;i=i+(++i)+i; System.out.println(i); 输出 5 即1+2+2
int i=1; i=i++; ystem.out.println(i); 输出 1
int i=1; i=2+i++; ystem.out.println(i); 输出 3
int i=1; i=(i++)+i ; System.out.println(i); 输出 3 即1+2
(可以看出等式左右边的 i ,右边的i在执行++i 或i++ 后如果在使用 i ,那么这个 i 就是已经自增了的
左右 i 值不同)
总结: 简单来理解 直接写 在外面 即方法内 i++和++i单独使用 是没问题的;
如果 int s; s=i++; int s; s=++i;采取赋值的话
和在 System.out.println(i++)或 System.out.println(++i)就遵循
运算符在前,先进行运算在使用此值,运算符在后先使用此值,再进行运算
(即i++先用后加,++i先加后用)