• 不用临时变量,只用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代码。
  • 相关阅读:
    Android studio ocr初级app开发问题汇总(含工程代码)
    面试题思路,25匹马 5个跑道取前三,前五,最少比赛次数--七次
    中国计算机学会推荐国际学术会议和期刊目录(CCF)2019年
    swift 数组部分排序
    SceneKit下关于修改SCNNode 的Shader展示自定义图形
    汇编语言实现字母下落效果
    组合数计算-java
    miniblast_hash算法c语言实现
    日常开发知识点备忘
    骑士周游问题跳马问题C#实现(附带WPF工程代码)
  • 原文地址:https://www.cnblogs.com/lutzmark/p/994467.html
Copyright © 2020-2023  润新知