本文转载自互联网,如有侵权,请联系我及时删除。谢谢。
第一个编程题是:用 C 语言写一个函数交换两整数的值,不借助第三个变量。
事实上这个题目一听到就有了想法,因为以前有做过,形如:
(方法一:)
a = a + b;
b = a - b;
a = a - b;
不过提出了最大的问题,就是两个正数的溢出问题。这个确实是缺限,以前遇到却没去找它的解决方法。
此时提出了强转类型为long int再做计算的想法(这时因为在想前面的问题没听懂)
然后基于这个想法提出了直接强转 double 运算完再转回 int,不过方法不可行
因为总需要将中间结果写到整型的a或b中,一样存在溢出的事实。
但大脸又提出了他的解法:
(方法二:)
a = a - b;
b = a + b;
a = b - a;
这方法以前决对没想过,原因在于方法一是从别的地方看到的,而非自己做出来的,没有解题过程的思维
乍一看,不存在两正数溢出的情况,不过在讨论中发现还是存在溢出的情况:一正数与一负数。
然后换了题目讨论而没有继续研究,直到过来问我他们的笔试题,我把知道的和他说了一下。
说到这题目时我把讨论的情况说了一下,不过说的过程中我发现了之前忽略的问题:
用方法一的话,溢出的可能性存在于:
1.两正数的交换
2.两负数的交换
即同号
于是又想了方法二,发现溢出的可能性存在于:
1.一正一负的交换
即异号
就这样综合一下得到了答案:
void swap(int *a, int *b){
if ((*a > 0 && *b > 0) || (*a < 0 && *b < 0)){ //同号
*a = *a - *b;
*b = *a + *b;
*a = *b - *a;
}
else { //异号
*a = *a + *b;
*b = *a - *b;
*a = *a - *b;
}
}
现在看来,其实这个并不难想到,只是发现自己解决问题时太依赖经验思维
尤其是对于认为简单的事情往往都没有换个角度进行思考,错失发现潜在事实的机会
这应该就是晚上的收获了。。
补充:睡觉前搜到这个东西,看了又无语了一次,相同的思维方式的另一个结果
void swap(int *a, int *b){
*a = *a ^ *b;
*b = *b ^ *a;
*a = *a ^ *b;
}
转载地址:http://blog.csdn.net/zhangxinrun/article/details/6040874