声明一下,我知道对于不同的C编译器,往往会产生一些不同的后果,但是我只想知道在TurboC2.0中的情况,以及在.NET 2.0中的他又是什么情况。

解决方案 »

  1.   

    更正一下,对于第二段代码:
    ~~~~~~~~~~~~
    int i =3;
    i = i++;
    打印i的值;
    ~~~~~~~~~~~~在TurboC2.0中的结果是4,在Dev C++中的结果是3,在VS2005中的结果是3。
      

  2.   

    @bandylau() 当然了解i++和++i的区别了,但是我这里是“i=i++”,始终都是i 啊,并不是什么“b=a++”或是“c=++a”啊?
      

  3.   

    可能我对第二段代码还没有解释清楚吧?
    ~~~~~~~~~~~~
    int i =3;
    i = i++;
    打印i的值;
    ~~~~~~~~~~~~
    我认为是i先赋值给i,然后i再执行++,在内存中,只有一个i,所以这里有一个++的操作,所以就应该是4啊??
      

  4.   

    呵呵,我不是很懂IL代码的,我贴出来,谁帮忙讲解一下啊?C#源码
    using System;
    using System.Collections.Generic;
    using System.Text;namespace ConsoleApplication2
    {
        class Program
        {
            static void Main(string[] args)
            {
                int i = 3;
                i = -i++;
                Console.WriteLine(i);
            }
        }
    }IL代码:
    .method private hidebysig static void  Main(string[] args) cil managed
    {
      .entrypoint
      // 代码大小       18 (0x12)
      .maxstack  3
      .locals init ([0] int32 i)
      IL_0000:  nop
      IL_0001:  ldc.i4.3
      IL_0002:  stloc.0
      IL_0003:  ldloc.0
      IL_0004:  dup
      IL_0005:  ldc.i4.1
      IL_0006:  add
      IL_0007:  stloc.0
      IL_0008:  neg
      IL_0009:  stloc.0
      IL_000a:  ldloc.0
      IL_000b:  call       void [mscorlib]System.Console::WriteLine(int32)
      IL_0010:  nop
      IL_0011:  ret
    } // end of method Program::Main对于第二段的代码:
    using System;
    using System.Collections.Generic;
    using System.Text;namespace ConsoleApplication2
    {
        class Program
        {
            static void Main(string[] args)
            {
                int i = 3;
                i = i++;
                Console.WriteLine(i);
            }
        }
    }IL代码:
    .method private hidebysig static void  Main(string[] args) cil managed
    {
      .entrypoint
      // 代码大小       17 (0x11)
      .maxstack  3
      .locals init ([0] int32 i)
      IL_0000:  nop
      IL_0001:  ldc.i4.3
      IL_0002:  stloc.0
      IL_0003:  ldloc.0
      IL_0004:  dup
      IL_0005:  ldc.i4.1
      IL_0006:  add
      IL_0007:  stloc.0
      IL_0008:  stloc.0
      IL_0009:  ldloc.0
      IL_000a:  call       void [mscorlib]System.Console::WriteLine(int32)
      IL_000f:  nop
      IL_0010:  ret
    } // end of method Program::Main
      

  5.   

    i = 3                  i = 3   
      i = -i++               i = i++
      打印i(结果为-3)      打印i(结果为3)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    IL_0000:  nop   IL_0000:  nop
    IL_0001:  ldc.i4.3   IL_0001:  ldc.i4.3
    IL_0002:  stloc.0   IL_0002:  stloc.0
    IL_0003:  ldloc.0   IL_0003:  ldloc.0
    IL_0004:  dup   IL_0004:  dup
    IL_0005:  ldc.i4.1   IL_0005:  ldc.i4.1
    IL_0006:  add   IL_0006:  add
    IL_0007:  stloc.0   IL_0007:  stloc.0
    IL_0008:  neg   IL_0008:  stloc.0 //差别就在这里,少了一个neg(即取负)
    IL_0009:  stloc.0   IL_0009:  ldloc.0
    IL_000a:  ldloc.0   IL_000a:  call  
    IL_000b:  call     IL_000f:  nop
    IL_0010:  nop   IL_0010:  ret
    IL_0011:  ret 希望有人讲解一下,谢了先~!
      

  6.   

    查了一下MSDN,看懂了IL代码,但是却是知其然不知其所以然,知道IL代码表达的是什么意思,怎样产生的这个结果,但却不明白为什么会是这个样子的,请高人指点。另外,对于为什么在Dev C++中运行“i = -i++”时,得到的结果和TurboC的结果一样,都是“-2”;但是对在Dev C++中运行“i = i++”的结果却又反过来和C#一样,都为“3”。这一点,依然很是迷惑~!还请高人指点。
      

  7.   

    i++这个东西只有在语句结束时才实现自增操作,也就是说在执行完赋值i=i++;这个操作后i的值才变化
      

  8.   

    i=i++,先执行i=i, ++如果不循环回来就永远不会调用,有别于 i=++i
      

  9.   

    @johnny1983() 不管如何,总之在语句结束后,还是要把i加1的,但是在后面的打印时,他确依然是-3或3,根本没有见++的操作效果
      

  10.   

    正常,C#是先计算表达式的值,然后再执行自增操作。
    所以int i = 3;
    i = -i++;这里 -i++作为表达式,其值是-3,然后进行自增,i变成4,最后赋值,则i = -3。C#对于同一个表达式,不同的版本的编译器总是得到确定的结果,而C++这个是未定义的操作,不同的编译器结果是不同的。C#有一个很重要的概念在于中间值,即表达式的一旦被计算完毕,则这个表达式再发生改动也不会影响这个计算结果。同样的如returnpublic static int MyMethod()
    {
      try
      {
        int i = 2;
        return i;
      }
      finally
      {
        i = 3;
      }
    }返回值是2
      

  11.   

    i = i++或类似的表达式:i = f( i++ ),在C++是未定义的操作,没有人知道i会是什么……
      

  12.   

    不管如何,总之在语句结束后,还是要把i加1的,但是在后面的打印时,他确依然是-3或3,根本没有见++的操作效果
    ----------------------------------
    IL的代码........
      IL_0000:  nop
      IL_0001:  ldc.i4.3  //将3压入栈
      IL_0002:  stloc.0   //3出栈
      IL_0003:  ldloc.0   //3再次压栈
      IL_0004:  dup       //复制栈上当前最顶端的值,然后将副本推送到栈上,就是再压一次3。
      IL_0005:  ldc.i4.1  //将1压入栈,此时栈上有1,3,3,一共3个值
      IL_0006:  add       //栈顶上两个值弹出,然后相加,把结果堆栈,此时栈上值为4,3
      IL_0007:  stloc.0   //4出栈
      IL_0008:  neg       //3出栈取反,然后压栈
      IL_0009:  stloc.0   //-3出栈
      IL_000a:  ldloc.0   //-3入栈
      IL_000b:  call       void [mscorlib]System.Console::WriteLine(int32)   //调用函数,参数为栈内元素,就是-3。
      IL_0010:  nop
      IL_0011:  ret       //返回这样看就清楚了点吧,4作为临时变量在取反前就消失了。
      

  13.   

    //调用函数,参数为栈内元素,就是-3。为避免混淆说明下,这里是为了保护断点局部变量压栈,函数调用的时候读取的应该是局部变量索引的数值,不过就值来说这两个是一样的。  IL_0001:  ldc.i4.3  //将3压入栈
      IL_0002:  stloc.0   //3出栈
      IL_0003:  ldloc.0   //3再次压栈这三句的意思实际是在局部变量索引0(就是i)设为3。并不是没有意义的。  IL_0007:  stloc.0   //4出栈
      IL_0008:  neg       //3出栈取反,然后压栈
      IL_0009:  stloc.0   //-3出栈
      IL_000a:  ldloc.0   //-3入栈
    而在这里,4出栈到局部变量索引0(就是i)
    然后i就被-3所覆盖了。
      

  14.   

    ◎Ivony
    ◎Fortner(好想退休) 谢谢你们的讲解,让我有种醍醐灌顶的感觉。
    ~~~~~~~~~~~~~~~~~~~~
    我做了一下总结放在Blog上了:http://www.cnblogs.com/BISer/archive/2007/07/25/831417.html