大家对这个自增运算符应该都很熟悉吧!
有前缀很后缀两种
前缀先自增在运算
后缀先运算后自增今天在和C#作比较时遇到一个问题。C#写法:
i = 2;
j = i + ++i;
输出j的值为5C/C++写法:
i = 2;
j = i + ++i;
输出j的值为6难道他们的运行机制不一样
为什么会这个
请高手帮忙作答
迫切想知道为什么C++中会得到6的结果顺祝各位中秋快乐!

解决方案 »

  1.   

    j = i + ++i;
    因为没有括号,所以实际是 i++ + i,,,,也就是3+3
    ++的运算级别比 +要高
      

  2.   

    C/C++写法:
    i = 2;
    j = i + ++i;
    应该也是输出5阿
      

  3.   

    会不会是C++不认识空格
    把楼主的 i+ ++i 理解成了i++ +i
    然后得出了6的结果?
      

  4.   

    一个是植 一个是址。编译器的问题C# 已经把i的 算出来了是2,在去算++i 是3,然后再 2+3。C++ 是址 i就是i 在去算++i,然后再i+i,=6。
      

  5.   

    咋把j=i+ ++i;写成j=i++ +i;
    结果又变成4了呢?
      

  6.   

    surnde你好。
    谢谢给出解答。
    各位仁兄能说的再详细点吗?如果C++中是用地址来参与运算的,那么我并没有通过&来获得它的地址啊
      

  7.   

    咋把j=i+ ++i;写成j=i++ +i;
    结果又变成4了呢?
    没错。我再vc中试了一下,如果这样写就是4
    呵呵,期待高人解答
    我一直以为得失,和空格没有关系,应该会自动取最大可能的运算符
    +++++,会取成++ ++ +
    如果这样的话,j应该等于5 pioneer_public() ( ) 信誉:100  2007-09-26 10:17:00  得分: 0  
     
     
       j = i + ++i;
    因为没有括号,所以实际是 i++ + i,,,,也就是3+3
    ++的运算级别比 +要高
      
    ------------------------------------------------ 
    如果这样应该是5,因为i++为2,此时i为3
      

  8.   

    ++的运算优先级比+高
    所以j=i+ ++i;
    会先算++i
    所以i=3
    j=3+3;
      

  9.   

    1。 結果為的5時,
        表達式右邊是“從左到右”
        開始算i+ ,然後才算++i,所以第一個i為2 ,第二個i 為3,2+3=5
     2。  結果為6時;
           表達式右邊是“從右到左”
        開始算++i ,i變為3,然後再算i+, 所以3+3=6;  只是他們的計算結構順序不同而已。
      

  10.   

    谁来回答我的问题啊~~~~咋把j=i+ ++i;写成j=i++ +i;
    结果又变成4了呢?
      

  11.   

    谁来回答我的问题啊~~~~咋把j=i+ ++i;写成j=i++ +i;
    结果又变成4了呢?
      

  12.   

    如果是写了个空格的话,应该是编译器"认"出了空格,运行结果跟加了括号一致.
    即j=i++ +i;结果为4,后增量是先将变量的值作为表达式的值确定下来,再将变量增1,实体值发生变化,只不过在当前表达式中,i的值还没体现实体中已经变化的值.
    如果不加空格,则编译器根据贪吃法则理解,尽可能多地理解操作符,所以i+++i与i+ ++i会得到4与6的结果
      

  13.   

    谁来回答我的问题啊~~~~咋把j=i+ ++i;写成j=i++ +i;
    结果又变成4了呢?------------------------------------------------
    那是后增量的问题,后增量的话i在这个表达式中是不代表实体的值的,即是说i的值是没增之前的值.而在下一个表达式中,i才代表实体的值,也即增后的值.
      

  14.   

    将 j = i + ++i; 看作 j = i++ +i; 这是不可能的.
    词法分析时,空格是作为分割符的.所以不可能发生两个分开的符号再合并重分配的情况.j = i+++i; 则确实需要根据优先级来的.但依据是后缀++比前缀++优先.这样+++优先拆出后缀++,从而变为 j = i++ +i;至于结果的不同.不仅在于C# 和C/C++的不同(C#不熟,可能在这方面有不同),其实不同的C++编译器也可以是不同的.依据是C++标准中的这段话(clause 5 [Exp] 4):Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified. Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored.The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefined. [Example:
    i = v[i++]; // the behavior is unspecified
    i = 7, i++, i++; // i becomes 9
    i = ++i + 1; // the behavior is unspecified
    i = i + 1; // the value of i is incremented
    —end example]所以  j = i + ++i; 以及 j=i++ +i; 都属于 unspecified .是先计算 ++i,i++ 还是先计算i,并且++的副作用什么时候有效,都是不定的.出现4,5,6的结果都有可能.当然对于同一个编译器和同一个表达式,结果是恒定的.
      

  15.   

    NOD,结合顺序差别影响了结果
      

  16.   

    这个和编译器有关吧,VC++不是 ANSI C++,有机会的话用gcc吧
      

  17.   

    这是我以前写的一篇文章..就是关于这个的..其实自己也觉得没有什么太大意义..不过多了解一点底层的东西还是没有害处的..#include <iostream>
    using namespace std;
    void main()
    {
        int n(0);
        int m(0);
        int i = (n++)+(n++)+(n++);
        int j = (++m)+(++m)+(++m);
        cout << "i:" << i << endl;
        cout << "j:" << j << endl;
    }
    程序会输出什么?很多程序员一看就知道答案,而且很明确的回答,i是0,j是7;
    但是程序并非想像中简单,或许更多的人连为什么得到上面的答案都不太清楚.
    我们首先在VC6.0下面反汇编一下程序
    13:       int i = (n++)+(n++)+(n++);
    004017B6 8B 45 FC             mov         eax,dword ptr [ebp-4]
    004017B9 03 45 FC             add         eax,dword ptr [ebp-4]
    004017BC 03 45 FC             add         eax,dword ptr [ebp-4]
    004017BF 89 45 F4             mov         dword ptr [ebp-0Ch],eax
    004017C2 8B 4D FC             mov         ecx,dword ptr [ebp-4]
    004017C5 83 C1 01             add         ecx,1
    004017C8 89 4D FC             mov         dword ptr [ebp-4],ecx
    004017CB 8B 55 FC             mov         edx,dword ptr [ebp-4]
    004017CE 83 C2 01             add         edx,1
    004017D1 89 55 FC             mov         dword ptr [ebp-4],edx
    004017D4 8B 45 FC             mov         eax,dword ptr [ebp-4]
    004017D7 83 C0 01             add         eax,1
    004017DA 89 45 FC             mov         dword ptr [ebp-4],eax
    14:       int j = (++m)+(++m)+(++m);
    004017DD 8B 4D F8             mov         ecx,dword ptr [ebp-8]
    004017E0 83 C1 01             add         ecx,1 //m自加004017E3 89 4D F8             mov         dword ptr [ebp-8],ecx
    004017E6 8B 55 F8             mov         edx,dword ptr [ebp-8]
    004017E9 83 C2 01             add         edx,1 //m自加
    004017EC 89 55 F8             mov         dword ptr [ebp-8],edx
    004017EF 8B 45 F8             mov         eax,dword ptr [ebp-8]
    004017F2 03 45 F8             add         eax,dword ptr [ebp-8]//first +
    004017F5 8B 4D F8             mov         ecx,dword ptr [ebp-8]
    004017F8 83 C1 01             add         ecx,1 //m自加
    004017FB 89 4D F8             mov         dword ptr [ebp-8],ecx
    004017FE 03 45 F8             add         eax,dword ptr [ebp-8] //second +
    00401801 89 45 F0             mov         dword ptr [ebp-10h],eax
    我们可以看到在VC环境下.代码14编译器是先把一个首先将两个m自加.然后调用了两个++m中间的+号,其实这个时候m的值已经变成2了,当调用+号加的时候,其实是表示2+2 = 4,然后将结果放入一个新的寄存器里面,然后调用最后一个m自加,最后一步调用第二个+号,运算,这个时候m为3了,所以结果变为4+3 = 7;而用同样的表达式,我们在vs2005.net下面运行的结果却又是另外一种情况,i是0,j是9;
    看看下面反汇编的程序:
    7:     int i = (n++)+(n++)+(n++);
    0041408C  mov         eax,dword ptr [n] 
    0041408F  add         eax,dword ptr [n] 
    00414092  add         eax,dword ptr [n] 
    00414095  mov         dword ptr [i],eax 
    00414098  mov         ecx,dword ptr [n] 
    0041409B  add         ecx,1 
    0041409E  mov         dword ptr [n],ecx 
    004140A1  mov         edx,dword ptr [n] 
    004140A4  add         edx,1 
    004140A7  mov         dword ptr [n],edx 
    004140AA  mov         eax,dword ptr [n] 
    004140AD  add         eax,1 
    004140B0  mov         dword ptr [n],eax 
         8:     int j = (++m)+(++m)+(++m);
    004140B3  mov         eax,dword ptr [m] 
    004140B6  add         eax,1 //m自加
    004140B9  mov         dword ptr [m],eax 
    004140BC  mov         ecx,dword ptr [m] 
    004140BF  add         ecx,1  //m自加
    004140C2  mov         dword ptr [m],ecx 
    004140C5  mov         edx,dword ptr [m] 
    004140C8  add         edx,1  //m自加 
    004140CB  mov         dword ptr [m],edx 
    004140CE  mov         eax,dword ptr [m] 
    004140D1  add         eax,dword ptr [m] //first+
    004140D4  add         eax,dword ptr [m] //second+
    004140D7  mov         dword ptr [j],eax 
    虽然不太明白vs2005.net编译的机制,但是可以从反汇编看出来,程序首先执行的是把m连续调用三次自加,最后才来调用操作符,而调用+的时候,m的值已经变成了3,所以最后的表达式就是3+3+3 = 9;最后我们把代码用C#语言编译一次,通过vs2005.net平台来进行反编译,我们又可以得到另外的一个结果,
    i是0,j是6,对于i是0这个东西,应该是所有语言和编译器都是一个样的,再来看看C#的反汇编:
    12:int n = (++i) + (++i) + (++i);
    0000002b  inc         esi  
    0000002c  mov         ebx,esi //自加一次然后将i的值赋值 
    0000002e  inc         esi  
    0000002f  add         ebx,esi //调用第一个加号
    00000031  inc         esi  
    00000032  add         ebx,esi //调用第二个加号
    00000034  mov         edi,ebx 
    不用说,C#机制绝对是最人性化的,也是我们比较容易理解的一种读取和执行代码.
    首先就是将i自加一次,然后将i赋值给一个临时变量,调用下一个i的时候,为了防止改变前面已经表达的i值,如果没有临时变量,我们直接加的就是i+i,那么很容易得到答案还是2+2,但是有了临时变量时,就变成了1+2,最后将结果放入另一个变量,最后调用最后一个i和加好,整个表达式变成了1+2+3 =6.觉得这样的思维方式跟人的思维方式比较相似.java和C下面的程序实现应该会得到其它结果,好久没有写java了,不知道怎么反汇编,呵呵..不过应该很容易的了解到,这道曾经的面试题应该考的并不是单纯的语言.还有一些很底层的知识.
      

  18.   

    研究过cout<<++i<<++i;的问题,在不同编译环境下,输出结果可能是不同的。
      

  19.   

    http://www.cyberspace.org/~jhl/ieqiplusplus_cn.html
      

  20.   

    http://www.cyberspace.org/~jhl/evalorder1_cn.html
      

  21.   

    c++对于表达式计算会先遍历是否有类似++i的结构,如果有则先计算所有++i,然后再进行计算。
      

  22.   

    跟优先级没有关系。标准C和C++对自增和自减没有做任何规定,各个编译器对其实现不同,对于你说的i = 2;j = i + (++i);,在VC中得到的结果j为6,在GCC中应该不同,不同的C/C++编译器对其处理是不同的。同样是上面的代码中java中得到的是5,java语言规范本身对自增做了规定,所以在java中都是一样的结果。另外一个例子:
    i = i /(i++);在VC中得到的是2,在java中得到的是1。在GCC中得到的好像也是1,GCC我没试过,但是应该和VC中不同。我想C#应该和JAVA的处理一样。
    关于这一点我是在java之父写的《java编程规范》一书中看到的,书上说java语言本身对自增作了规定,所以不同java编译器中能得到相同结果。同时该书上也指出标准C(ANSI C)没有对C的自增作出规定,所以不同的C编译器对它进行了不同的实现。
      

  23.   

    晕,c/c++中 i = 2;j = i+  ++i;j的值当然是6了,记住这样一条规则:++在前时,程序是先用变量然后才对变量++;++在后时,程序是先对变量++然后再用变量。
    上边的例子中,++在i之前,所以i先自己++,变成3,然后系统再用i,这是i = 3;所以j = 3 + 3;
    郁闷,麻烦不懂得先把运算符的优先级搞清楚。
    还有就是j = i++ +i,程序是先用i,之后再++,也就是相当于先 j = 2 + 2;计算完毕之后i++,所以这行代码运行完之后j = 4; i = 3.
      

  24.   

    My god, you stupid monkeys!