zoukankan      html  css  js  c++  java
  • 不用临时变量,只用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代码。
  • 相关阅读:
    读书笔记--SQL必知必会07--创建计算字段
    读书笔记--SQL必知必会06--用通配符进行过滤
    读书笔记--SQL必知必会05--高级数据过滤
    FontMetrics ----- 绘制文本,获取文本高度
    Android 防止控件被重复点击
    提高zxing生成二维码的容错率及zxing生成二维码的边框设置
    Android 异常解决方法【汇总】
    setFocusable、setEnabled、setClickable区别
    getView 数据最后加一项
    TextView字体和背景图片 设置透明度
  • 原文地址:https://www.cnblogs.com/lutzmark/p/994467.html
Copyright © 2011-2022 走看看