最近看到这样一道关于自加运算的题,空闲的时候想一想觉得有点意思:
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

解决方案 »

  1.   

    c=c++; c++这个表达式的值是1;把1赋值给c,所以c的值是1。
      

  2.   

    c=c++;
    ============
    个人认为等于
    c=c;
    c+1;
      

  3.   

    好像前面有人问过这个
    c=c++
    分解出来就是
    int temp = c;
    c = temp + 1;
    c = temp;
      

  4.   

    看来C++和JAVA在这些细节的运算逻辑上还真是...
      

  5.   


    请大家看看3楼。不是java的逻辑有问题,而是这句话根本不会执行!

      

  6.   


    这题的关键是这一行的理解。牵扯到一个赋值的基本概念。java的赋值与c/c++一样的,右边的赋给左边的,c = c++ 其实等价于 c = 某个数字至于这个数字内部如何结构,c不关心。一但这个数字赋给c,那么c的值就确定了。接下去a = c,这是将c的值赋给a,根据右侧赋给左侧的基本原则,a 取 c = c++; 中左侧的这个值至于右侧的c++,a不会去关心。也就是说,c = c++; 等价于 c = c; 等价于 c = 1;
      

  7.   


    我个人不同意这种观点。由于没有循环,因此 c = c++ 之被执行了一次,即 c = c;而 ++ 的部分要在下一次循环时才执行。而且Java的执行是与c/c++一样,即按行来执行,若没有循环,已运行过的行将不被再次执行以这道题目为例:c = c++; //  这时 c = c = 1
    a = c // 这时 a = c = 1;由于++在上一行,程序不可能反上去再执行,因此++就被跳过了。
      

  8.   

    虽没什么实用价值,不过可以反映出运算符的优先级和Java处理++运算的逻辑,=的优先级要低于++运算符,所以楼主的分析正确。
      

  9.   

    c=c++把运算符看成方法的调用{所以有的语言可以运算符重载}在前的++(int o){
       o=o+1;
       return o;
    }在后的++ (int o){
      int temp=o;
      o=o+1;
      return temp;
    }++运算大致应该是这样实现的
    所以会发生LZ的情况
      

  10.   

    确实c=c++;这句没有执行...如果改为c++结果就为2,2
      

  11.   

    经典...不过后面的++还是有o=o+1; o还是加了1,或许就是没有赋值成功,但是同样的程序在C++里就得到了结果2,不知道JAVA是如何计算了...
      

  12.   

    请看Disassembles结果,这句绝对会执行!
    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编译器的行为,要用事实说话!
      

  13.   

    其实可以再试一下
    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++;
        }
    }
    就知道++执行没有了...不过其实也不用想那么多..出边了..
      

  14.   


    ??我昨天用C++试的结果同JAVA的一样,C=1 A=1
      

  15.   

    int c=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;
      

  16.   

    System.out.println(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自加后被无情的从内存中咔嚓以上纯属猜想无法证明 嘎嘎
      

  17.   

    呵呵,这个问题在csdn已经回答至少3遍了,去看看其他帖子吧
      

  18.   

    有心情的朋友可以试验运行稍微复杂一点的代码(有些东西变复杂了,反而能看清楚...)int c=1;
    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=常量;这种简单的赋值形式,可以说这是将复杂化简单的一般性方法吧,底层实现没理由不这么做。当然至于底层具体怎么实现的,不清楚。