您的位置:首页 > 职场人生

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

2013-10-18 13:46 295 查看
本文没有针对任何人、任何文章的意思,只是自我反省的一篇博文,提醒自己以后多多思考问题、深入问题。

早上刚刚看到这篇博文“面试奇葩——交换两变量值的一些邪门歪道(/article/4776543.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 \n" , i , j );

   swap( & i , & j);

   puts("交换后:");

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

   //自己和自己交换

  puts("交换前:");

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

  swap( & i , & i);

  puts("交换后:");

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

  return 0;

}

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

本文没有针对任何人、任何文章的意思,只是自我反省的一篇博文,提醒自己以后多多思考问题、深入问题。透过现象看待问题的本质。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐