最近看到这样一道关于自加运算的题,空闲的时候想一想觉得有点意思:
public class Plus {
public static void main(String[] args) {
int c=1;
int a;
c=c++;
a=c;
System.out.println("c = "+c+" a="+a); } }
结果是c = 1 a = 1 想起来好像是这个意思,我们一般觉得如果x=y++;那么先把y的值赋给x然后y的值再自加1,不过好像并不是这样,上面那道题就说明了这个问题,如果c=c++;先把c的值(1)赋给c,再把c的值自加1,则得c=2;可是c为1,如果按照这个结果逻辑应该是这样的:作为表达式c++首先要计算出将要赋给左边c的值为1,然后(或者是同时)c进行自加1运算,得到c为2,最后一步是把刚才计算出的要赋给左边c的表达式的值(也就是刚才计算出的1)赋给c,这时这个1将刚才c自加1得到的2覆盖,所以最后的结果为c=1,a=1
public class Plus {
public static void main(String[] args) {
int c=1;
int a;
c=c++;
a=c;
System.out.println("c = "+c+" a="+a); } }
结果是c = 1 a = 1 想起来好像是这个意思,我们一般觉得如果x=y++;那么先把y的值赋给x然后y的值再自加1,不过好像并不是这样,上面那道题就说明了这个问题,如果c=c++;先把c的值(1)赋给c,再把c的值自加1,则得c=2;可是c为1,如果按照这个结果逻辑应该是这样的:作为表达式c++首先要计算出将要赋给左边c的值为1,然后(或者是同时)c进行自加1运算,得到c为2,最后一步是把刚才计算出的要赋给左边c的表达式的值(也就是刚才计算出的1)赋给c,这时这个1将刚才c自加1得到的2覆盖,所以最后的结果为c=1,a=1
解决方案 »
- 请叫大牛们如何学习好JAVA的基础,谢谢你们
- 在Java中的RSA加解密问题
- 用java 取whois 的问题
- 在线等,关于switch case语句的问题,执行后结果不对,谁来帮下哈
- 高手帮我看一下,此程序有什么问题?
- 一个sourceStr.replaceFirst(regStr,repStr)的问题,返回“Illegal Group Reference”异常,请大虾帮忙!
- 怎么在JSP中调用JAVA 的一些命令来执行,如果调用JAVAC,keytool,JAR 等命令。
- IE不运行 APPLET !!!!!help me plz!~
- 一个奇怪的文件输出问题,还请高手指点!!!!
- 在线求教:关于声音!
- 一个简单的问题
- 網頁問題
============
个人认为等于
c=c;
c+1;
c=c++
分解出来就是
int temp = c;
c = temp + 1;
c = temp;
请大家看看3楼。不是java的逻辑有问题,而是这句话根本不会执行!
这题的关键是这一行的理解。牵扯到一个赋值的基本概念。java的赋值与c/c++一样的,右边的赋给左边的,c = c++ 其实等价于 c = 某个数字至于这个数字内部如何结构,c不关心。一但这个数字赋给c,那么c的值就确定了。接下去a = c,这是将c的值赋给a,根据右侧赋给左侧的基本原则,a 取 c = c++; 中左侧的这个值至于右侧的c++,a不会去关心。也就是说,c = c++; 等价于 c = c; 等价于 c = 1;
我个人不同意这种观点。由于没有循环,因此 c = c++ 之被执行了一次,即 c = c;而 ++ 的部分要在下一次循环时才执行。而且Java的执行是与c/c++一样,即按行来执行,若没有循环,已运行过的行将不被再次执行以这道题目为例:c = c++; // 这时 c = c = 1
a = c // 这时 a = c = 1;由于++在上一行,程序不可能反上去再执行,因此++就被跳过了。
o=o+1;
return o;
}在后的++ (int o){
int temp=o;
o=o+1;
return temp;
}++运算大致应该是这样实现的
所以会发生LZ的情况
public class Test {
public static void main(String[] args) {
long i = 1;
}
}
public class Test {
public static void main(String[] args) {
long i = 1;
i = i++;
}
}
Disassembles后
Code:
0: iconst_1
1: istore_1
2: return
0: iconst_1
1: istore_1
2: iload_1
3: iinc 1, 1
6: istore_1
7: return注意多出来的三个指令,其中iinc 1, 1对应++运算!
程序本身没什么价值和逻辑,但Java编译器不会知道的!
不要猜测Java编译器的行为,要用事实说话!
Java codepublic class Test {
public static void main(String[] args) {
long i = 1;
i = i;
}
}Java codepublic class Test {
public static void main(String[] args) {
long i = 1;
i = i++;
}
}
就知道++执行没有了...不过其实也不用想那么多..出边了..
??我昨天用C++试的结果同JAVA的一样,C=1 A=1
c=c++;(此处c++在表达式里的值等于1,
验证可以执行System.out.println(c++); 控制台会输出1)
于是c=c++执行过程中可能存在一步转化操作,将其转换为c=1;
执行过程应该是这样
第一步、将c=c++;转换成为c=1;(但还没执行c=1这个表达式)
第二不、执行c++,将c的自增变为2;
第三步、执行c=1,将c的值赋值为1;
c=c++我支持这种说法
int temp =c;
c=temp++;
结果 c=1 temp从内存中咔嚓掉了我是这么想的,声明变量就是在内存中申请个存放数据的空间,附值就是往内存空间中放数据,并且重新附值是
等号右边的值覆盖等号左边的内存空间
c++ 相当于 c=c+1
等号左边名为c的内存空间里存放的是数据c,而他无法改变只能别被新的数据覆盖
而等号右边应该是内存里新开辟的临时空间里面存放的是经cpu计算的数据(c+1)用于覆盖名为c的内存空间
就是说 变量里存放的数据只能被新的数据覆盖 而无法自己进行+1运算保留结果 c+1要由cpu运算并将结果覆
盖回去
相当于
int temp = c+1;
c=temp;
同理 c=c++;相当于
int temp=c;
c=temp++;
结果c=1 temp自加后被无情的从内存中咔嚓以上纯属猜想无法证明 嘎嘎
c=c++ + c++ + c++;
System.out.print(c);执行过程应该是:
1、将c=c++ + c++ + c++;转化为c=1 + c++ + c++; 然后运行一次c++,将c的自增为2;2、将c=1 + c++ + c++; 转化为c=1 + 2 + c++; 然后,运行一次c++,将c的自增为3;
3、将c=1 + 2 + c++; 转化为c=1 + 2 + 3; 然后,运行一次c++,将c的自增为4;
4、将c=1 + 2 + 3;转化为 c=6;
5、执行c=6,将c的值附为6;
所有打印语句System.out.print(c);会在控制台打印出6;当c=c++;只是简单了一点而已...
将 c=c++; 这种复杂的赋值语句转换为 c=常量;这种简单的赋值形式,可以说这是将复杂化简单的一般性方法吧,底层实现没理由不这么做。当然至于底层具体怎么实现的,不清楚。