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

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

早上刚刚看到这篇博文“面试奇葩——交换两变量值的一些邪门歪道(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,保险的话你写在程序里,就没有问题了

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

原文地址:https://www.cnblogs.com/bjlhx/p/3375828.html