现在的位置: 首页 > 综合 > 正文

Java 和 C/C++ 中的++的比较

2014年02月03日 ⁄ 综合 ⁄ 共 4624字 ⁄ 字号 评论关闭

今天在希赛网看到有个提问“《JAVA解惑》一书上有一个题,说的是i=i++执行的时候,i值前后不变。我看完书试验了一下,果然!然后又用C语言(TC2.0)试验,发现i=i++后数值增加1……

请高人们指点一下,Java里的赋值的时候,到底后缀的自增运算符和赋值运算之间是怎样一个顺序?为什么会得0?为什么C就得1了呢?”

闲着也是闲着,就回复了一篇

一、先谈后++:

   1. java里, 在表达式运算中,++执行后的结果参加表达式运算。
   如果不明白什么意思,看下面例子:
   
   Example 1:
   Line 1:  i = 0;
   Line 2:  System.out.println(i++); //输出 0;
   Line 3:  System.out.println(i);   //输出 1;       
   
   分析:i++值是0, 但是i++执行后i是1,所以Line 2输出是0,
   Line 3输出是1.
   至于赋值,java 是这样的, 如 i = i++; 因为从Line 2可以得知i++值是0,
   所以 i = i++; 即 i = 0; 而C/C++却不是这样的.见C/C++中的说明
   
   Example 2:
   Line 4:  i = 0;
   Line 5:  System.out.println(i++ + i++); //  0 + 1; 输出1
   Line 6:  System.out.println(i);         //  2; 输出2        
   
    分析:Line 5中第一个i++值是0,但是i++ 执行后,i值是1;由于执行到
    第二个i++的时候i的值是1,所以第二个i++的值是1,执行后i值是2.   
   
    Example 3:
    Line 7:  i = 0;
    Line 8:  System.out.println(i++ + i++ + i++); // 0 + 1 + 2; 输出3
    Line 9:  System.out.println(i);               // 3;  输出3
   
    分析:Line 8中第一个i++值是0,但是i++ 执行后,i值是1;由于执行到
    第二个i++的时候i的值是1,所以第二个i++的值是1, 执行后i值是2; 由
    于执行到第三个i++的时候i的值是2, 所以第二个i++的值是2, 执行后i
    的值是3
   
    依此类推.
   
   

    2. 而在C/C++中,后++是在整个表达式运算结束以后进行的.
   
   Example 4:
   Line 10:  i = 0;
   Line 11:  printf("%d/n", i++); //输出 0;
   Line 12:  printf("%d/n", i);   //输出 1;   

   分析:i++值是0, 但是i++执行后i是1,所以Line 11输出是0,
   Line 12输出是1.
   上面已经说到后++是在整个表达式运算结束以后进行的.
   所以i=i++中的++是在表达式运算结束后进行.
   
   i = 0;
   printf("%d/n", i=i++); //i++为0, i=i++ 这是一个表达式,它的值依然是0,输出 0;
   printf("%d/n", i);     //i=i++结束后,进行自加,输出 1;
      
   Example 5:
   Line 13:  i = 0;
   Line 14:  printf("%d/n", i++ + i++); //  0 + 0; 输出0,
   Line 15:  printf("%d/n", i);         //  2; 输出2,自增两次
   
    分析:Line 14中i++ + i++是一个表达式,在执行过程中,i不自增加,
    待整个表达式执行完毕后,i自增
   
    Example 6:
    Line 16:  i = 0;
    Line 17:  printf("%d/n", i++ + i++ + i++); // 0 + 0 + 0; 输出0
    Line 18:  printf("%d/n", i);               // 3;  输出3
   
    分析:同上
   
二、再谈前++:  
   1. java里, 在表达式运算中,++先执行后,然后执行表达式运算。
   如果不明白什么意思,还得看下面例子:
   
   Example 7:
   Line 19: i = 0;
   Line 20:  System.out.println(++i); //输出 1;
   Line 21:  System.out.println(i);   //输出 1;   

   分析:++i值是1, ++i执行后i也是1,所以Line 20和Line 21输出结果相同,都是1
   
   Example 8:
   Line 22:  i = 0;
   Line 23:  System.out.println(++i + ++i); //  1 + 2; 输出3
   Line 24:  System.out.println(i);         //  2; 输出2        
   
    分析:Line 23中第一个++i值是1,++i 执行后,i值也是1;由于执行到
    第二个++i的时候i的值是1,所以第二个++i的值是2,执行后i值是2
   
    Example 9:
    Line 25:  i = 0;
    Line 26:  System.out.println(++i + ++i + ++i); // 1 + 2 + 3; 输出6
    Line 27:  System.out.println(i);               // 3;  输出3
   
    分析:同上       
       
    依此类推.
   
  2. 在C/C++中,和java中一致,唯一的区别在于使用的寄存器不同,这也有可能导致
    最终运算结果不同.可以看一下Example 11 和 Example 12
   
   Example 10:
   Line 28:  i = 0;
   Line 29:  printf("%d/n", ++i); //输出 1;
   Line 30:  printf("%d/n", i);   //输出 1;   

   分析:++i值是1,++i执行后i是1,所以Line 29和Line 30输出都是1
   
   Example 11:
   Line 31:  i = 0;
   Line 32:  printf("%d/n", ++i + ++i); //  2 + 2; 输出4,
   Line 33:  printf("%d/n", i);         //  2; 输出2,自增两次
   
    分析:Line 32 的输出结果有可能大家都比较迷惑,为什么是2 + 2, 而不是1 + 2.
    这里还得从它的汇编代码研究.    
     0040D728   mov         dword ptr [ebp-4],0      // i = 0;
     0040D72F   mov         eax,dword ptr [ebp-4]   
       0040D732   add         eax,1                    // 第一个 ++i;
    0040D735   mov         dword ptr [ebp-4],eax    // i = 1;
    0040D738   mov         ecx,dword ptr [ebp-4]    //
    0040D73B   add         ecx,1                    // 第二个 ++i;                                
    0040D73E   mov         dword ptr [ebp-4],ecx    // i = 2
    0040D741   mov         edx,dword ptr [ebp-4]    // edx 是求和的值,可以看到并不是使用mov edx eax; add edx dword ptr [ebp-4]
    0040D744   add         edx,dword ptr [ebp-4]    // 所以得到的是2+2, 而不是1+2
    0040D747   push        edx
    其实继续加下去的话,可以清楚地了解其中的道理,在Example 12中加以说明   
   
    Example 12:
    Line 34:  i = 0;
    Line 35:  printf("%d/n", ++i + ++i + ++i + ++i); // 2 + 2 + 3 + 4; 输出11
    Line 36:  printf("%d/n", i);               // 4;  输出4
   
    分析:  还得看汇编代码:   
    0040D728   mov         dword ptr [ebp-4],0       // i = 0;
   0040D72F   mov         eax,dword ptr [ebp-4]    
   0040D732   add         eax,1                     // 第一个++i
   0040D735   mov         dword ptr [ebp-4],eax     // i = 1;
   0040D738   mov         ecx,dword ptr [ebp-4]    
   0040D73B   add         ecx,1                     // 第二个++i 
   0040D73E   mov         dword ptr [ebp-4],ecx     // i = 2; 
   0040D741   mov         edx,dword ptr [ebp-4]     //注意这里!!!!!!!
   0040D744   add         edx,dword ptr [ebp-4]     // 在Example 11中有说明,edx 是求和的值,和的值只用了这一个寄存器
                            //所以第一次 + 运算时就出现了 2 + 2情形, 此时edx即为4
   0040D747   mov         eax,dword ptr [ebp-4]    
   0040D74A   add         eax,1                     //第三个 ++i
   0040D74D   mov         dword ptr [ebp-4],eax     // i = 3;
   0040D750   add         edx,dword ptr [ebp-4]     // edx = edx + 3 = 4 + 3 = 7;
   0040D753   mov         ecx,dword ptr [ebp-4]    
   0040D756   add         ecx,1                     //第四个 ++i
   0040D759   mov         dword ptr [ebp-4],ecx     // i = 4;
   0040D75C   add         edx,dword ptr [ebp-4]     // edx = edx  + 4 = 7 + 4 = 11;
   0040D75F   push        edx
      
       结束运算,Line 35输出结果为11; Line 36 输出结果为i=4,
      
       依此类推
        

抱歉!评论已关闭.