针对博文“面试奇葩——交换两变量值的一些邪门歪道 ”的一些编程深思--希望大牛多多光临、指导
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,保险的话你写在程序里,就没有问题了
本文没有针对任何人、任何文章的意思,只是自我反省的一篇博文,提醒自己以后多多思考问题、深入问题。透过现象看待问题的本质。。。
早上刚刚看到这篇博文“面试奇葩——交换两变量值的一些邪门歪道(/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,保险的话你写在程序里,就没有问题了
本文没有针对任何人、任何文章的意思,只是自我反省的一篇博文,提醒自己以后多多思考问题、深入问题。透过现象看待问题的本质。。。
相关文章推荐
- 面试奇葩——交换两变量值的一些邪门歪道
- 交换两变量值的一些邪门歪道
- 冲向大牛之安卓---2014.11月面试经常碰到的一些问题
- 最近面试的一些经验和总结,希望给跳槽的朋友一些借鉴
- 游戏程序员面试总结---希望给有用的着的人一些帮助
- 学习struts 浅要的理解 希望大牛指导
- 【小松教你手游开发】【面试必读(编程基础)】开始构建三维图形引擎:点、向量和一些基本概念
- 想诚心学习IOS,只是不知道如何下手,希望前辈能多多指导!
- 最近面试的一些经验和总结,希望给跳槽的朋友一些借鉴
- socket编程的一些名词总结,针对菜鸟
- 有关网络编程的一些面试
- 学习编程的经典语录(希望这些经典语录可以对决定踏上计算机之路的你有一些启发)
- 面试一些简单的编程题目
- 好长时间上不了博客,我还以为因为我发表抗日言论账户被删了,编程中好多新经验新发现不能拿出来和朋友们分享,那个急呀。以下是我在工作中积累的一些经验和解决的一些问题,希望能对大家有一点帮助。
- 关于Apache 工具包的一些记录,希望以后项目可以多多使用。
- C# DevExpress WinForm编程 针对一些控件重复度高的属性设置问题的解决方案
- 【大牛之路】大牛指导,报酬丰厚的开源项目---“谷歌编程之夏”
- 面试的时候你碰会到一些奇葩的面试官!(一)
- Java中String的一些使用技巧(针对面试s)
- 面试之变量值交换