zoukankan      html  css  js  c++  java
  • 针对博文“面试奇葩——交换两变量值的一些邪门歪道 ”的一些编程深思--希望大牛多多光临、指导

    本文没有针对任何人、任何文章的意思,只是自我反省的一篇博文,提醒自己以后多多思考问题、深入问题。

    早上刚刚看到这篇博文“面试奇葩——交换两变量值的一些邪门歪道(http://www.cnblogs.com/pmer/p/3373843.html)”。

    才发现自己的思考越来越少了,背诵越来越多了

    以前只是想,交换两个标量有这么多的方法,背下来,以后面试用。哈。装B一下。。

    可是却没有深入思考程序的可用性、以及实用性。更深层次的去理解内部的东东。。

    模仿garbageMan同志的思路走下去。。(个人也思考了一下这些问题)

    int i = 111, j = 222;

    1.值类型变量交换----借助第三个变量(这个估计通用,没啥说的)

        #region 值类型变量交换----借助第三个变量
               Console.WriteLine("i:" + i + ",j:" + j);
                int temp = 0;
                temp = i;
                i = j;
                j = temp;
                Console.WriteLine("i:" + i + ",j:" + j);
                #endregion

    2.值类型变量交换----加法(这个有点意思),深入了一下

    直接考虑极值

      i = int.MaxValue;   //最大值啊

      j = int.MaxValue - 1;            

      Console.WriteLine("i:" + i + ",j:" + j);            

      //i=2147483647,,,,j=2147483646    //开始时候的值

      i = i + j;             //加法啊

      Console.WriteLine("i:" + i + ",j:" + j);            

      //估计这时候后 就是学名的溢出,但是,计算的时候估计是把符号位一起计算上了,,使得最高位符号位由0变1 ,i结果也就变成了-3            

      //i=-3 ,,,,,j=2147483646

      j = i - j;

      i = i - j;

      //这两步是交换计算  

              

      Console.WriteLine("i:" + i + ",j:" + j);            

      //i=2147483646,,,,j=2147483647            

      //估计内部计算,会把这个最高位的符号位,一起参与计算了。结果使得结果正确。。

    语法课本说这是“溢出”,,但实际确是,没有编译报错,执行没有报错,,估计直接把符号位,拉进了计算。。

    应该是cpu计算的时候没有什么符号位,只不过是程序语言底层把有符号数的第一位翻译成符号位,在cpu内部直接就是高地位的计算。个人理解,(不太了解具体内部,,希望大牛详解)

    3.值类型变量交换----乘除法,直接pass啦

        #region 值类型变量交换----乘除法,直接pass啦  j=0 编译器会直接报错,估计是对“/”除法有着最基本的校验重写
                //i = i * j;
                //j = i / j;
                //i = i / j;
                #endregion

    4.值类型变量交换----整形 异或运算,相异出1

    #region 值类型变量交换----整形 异或运算,相异出1

      i = int.MaxValue; j = int.MaxValue - 1;            

      Console.WriteLine("i:" + i + ",j:" + j);//i=2147483647,j=2147483646            

      i = i ^ j;            

      Console.WriteLine("i:" + i + ",j:" + j);//i=1,j=2147483646            

      j = j ^ i;            

      Console.WriteLine("i:" + i + ",j:" + j);//i=1,j=2147483647            

      i = i^j;            

      Console.WriteLine("i:" + i + ",j:" + j);//i=2147483646,j=2147483647            

      #endregion

    这个确实,只是用与整数运算,浮点类型等类型不适用。。

    5.对于上文笔者提到的异或潜在问题(同一个数交换数值),有点不敢苟同

    #include <stdio.h>

    #include <limits.h>

    void swap( int  * p , int * q )

    {  

     * p = * p ^* q ;  //这里取相同地址的值,是同一个数值 ,10(上一次交换的) ,两个相同的数值异或结果为0,这时候赋值给*p,而*p、*q有指向同一地址,所以p、q都是0
     * q = * q^* p ;   //这里两者都是0
     * p = * p^* q ; //这里两者都是0

    }

    int _tmain(int argc, _TCHAR* argv[])

    {  

      int i = 5 , j = 10 ;

       puts("交换前:");  

      printf("i = %d , j = %d " , i , j );

       swap( & i , & j);

       puts("交换后:");  

      printf("i = %d , j = %d " , i , j );

       //自己和自己交换  

      puts("交换前:");  

      printf("i = %d " , i );

       swap( & i , & i);

       puts("交换后:");

       printf("i = %d " , i );

       return 0;

    }

    同一个数异或本身就是0,这是后你又使用指针,指向同一个地址,所以都是指向0的地址,以后再怎么异或都是0和0异或了,所以就是0,保险的话你写在程序里,就没有问题了

    本文没有针对任何人、任何文章的意思,只是自我反省的一篇博文,提醒自己以后多多思考问题、深入问题。透过现象看待问题的本质。。。

  • 相关阅读:
    新mac本安装Homebrew姿势(大前提:需要FQ)
    git 常用命令
    elementUI 函数自定义传参
    微信小程序避坑指南——echarts层级太高/层级遮挡
    前端向后端传递formData类型的二进制文件
    elemetnUI表格分别给列表每一个按钮加loading
    前端获取cookie,并解析cookie成JSON对象
    elementUI 输入框用户名和密码取消自动填充
    AOP面向切面编程
    关于ArrayList、HashSet、HashMap在并发下不安全的实例以及解决办法
  • 原文地址:https://www.cnblogs.com/bjlhx/p/3375828.html
Copyright © 2011-2022 走看看