不用临时变量,只用11个字符交换两个变量的值——窥视C#编译原理的冰山一角

 曾经有一道题,已知:  
  int   a,   b;  
  并已赋值,值的唯一限制是int.MinValue<=a,b<=int.MaxValue,所有极端情况均有可能  
  例如   a   =   2147483647,   b   =   2147000000  
  又或   a   =   -2147483600,   b   =   -2147483640  
  又或   a   =   2000000000,   b   =   -2000000000  
  当然也包括   a   =   0,   b   =   0   (-_-)  
   
  现在要将a,b的值交换  
   
  没有任何导入的命名空间(即如果你要用类,必须从System开始写起)  
  没有任何辅助的方法(即如果你要辅助方法,你要自己写)  
  除了a和b没有其它已经声明的字段或参数或局部变量,  
   
  并且不能再声明任何变量!  
   
  求最短的、编译可以通过的、所有情况下都能达到目的的   C#   代码   
    
   用来测试的代码:  
  class   Program  
  {  
          static   void   Main()  
          {  
                  int   a   =   1234567890,   b   =   987654321;  
                  /**************************\  
                    *   将你的答案填入下面两个斜杠内   *  
                    *//*  
                    *   将你的答案填入上面两个斜杠内   *  
                  \**************************/  
                  System.Console.WriteLine("a={0},b={1}",   a,   b);  
                  System.Console.ReadLine();  
          }  
  }  



正确的解法是:
a   =   b   +   (   b   =   a   )   *   0

编译原理:
首先编译器根据运算符优先级,先找到这个里面最优先的运算符*,确定结合顺序如下:
a   =   (   b   +   (   (   b   =   a   )   *   0   )   )

接下来,根据C#规范,会从左至右计算每个子表达式的值,第一个子表达式b,值为当前b值,记为b &apos;,第二个子表达式b   =   a,值为当前a值,记为a &apos;,最后一个表达式0,值为0。

接下来,根据刚才确定的顺序,依次进行计算。
b   =   a已经运算完毕,值为a &apos;,这时进行乘法运算,然后进行加法运算,然而C#的编译器意识到这个加法是没有意义的,故而优化掉,所以,整个表达式被优化为:
a   =   b &apos;

加上刚才计算子表达式的值时计算的b   =   a。

故而C#的编译器做出了最简的IL代码。

你可能感兴趣的:(编译原理)