用异或来交换两个变量更耗时
来源:互联网 发布:js的json字符串转数组 编辑:程序博客网 时间:2024/06/14 10:28
FROM:陈硕 http://blog.csdn.net/solstice/article/details/5166912
翻转一个字符串,例如把 "12345" 变成 "54321",这是一个最简单的不过的编码任务,即便是 C 语言初学者的也能毫不费力地写出类似如下的代码:
// 版本一,用中间变量交换两个数,好代码
void reverse_by_swap(char* str, int n)
{
char* begin = str;
char* end = str + n - 1;
while (begin < end) {
char tmp = *begin;
*begin = *end;
*end = tmp;
++begin;
--end;
}
}
这个代码清晰,直白,没有任何高深的技巧。
不知从什么时候开始,有人发明了不使用临时变量交换两个数的办法,用“不用临时变量 交换 两个数”在 google 上能搜到很多文章。下面是一个典型的实现:
// 版本二,用异或运算交换两个数,烂代码
void reverse_by_xor(char* str, int n)
{
// WARNING: BAD code
char* begin = str;
char* end = str + n - 1;
while (begin < end) {
*begin ^= *end;
*end ^= *begin;
*begin ^= *end;
++begin;
--end;
}
}
受一些过时的教科书的误导,有人认为程序里少用一个变量,节省一个字节的空间,会让程序运行更快。这是不对的,至少在这里不成立:
1. 这个所谓的“技巧”在现代的机器上只会更慢(我甚至怀疑它从来就不可能比原始办法快)。原始办法是两次内存读和写,这个"技巧"是六读三写加三次异或(或许编译器可以优化成两读三写加三次异或)。
2. 同样也不能节省内存,因为中间变量 tmp 通常会是寄存器(稍后有汇编代码供分析)。就算它在函数的局部堆栈(stack)上,反正栈已经开在那儿了,也没有进一步的函数调用,根本节约不了一丁点内存。
3. 相反,由于计算步骤较多,会使用更多的指令,编译后的机器码长度会增加。(这不是什么大问题,短的代码不一定快,后面有另外一个例子。)
这个技巧的意义完全在于应付变态的面试,所以知道就行,但绝对不能放在产品代码中。我也想不出问这样的面试题意义何在。
更有甚者,把其中三句:
*begin ^= *end;
*end ^= *begin;
*begin ^= *end;
写成一句:
*begin ^= *end ^= *begin ^= *end; // WRONG
(a^=b^=a^=b;)
这更是大有问题,会导致未定义的行为(undefined behavior)。C 语言的一条语句中,一个变量的值只允许改变一次,像 x = x++ 这种代码都是未定义行为。在C语言里没有哪条规则保证这两种写法是等价的。
(致语言律师:我知道,黑话叫序列点,一个语句可能不止一个序列点,请允许我在这里使用不精确的表述。)
这不是一个值得炫耀的技巧,只会丑化劣化代码。
- 用异或来交换两个变量更耗时
- 用异或来交换两个变量是错误的
- 用异或来交换两个变量效率分析
- 用异或来交换两个变量是错误的
- 用异或来交换两个变量是错误的
- 用异或来交换两个变量不一定提高了效率
- 用异或来交换两个变量能提高速度是错误的
- 用异或交换两个变量的分析
- 两个变量异或法交换值
- 用异或来交换变量是错误的
- 不使用temp变量来交换两个值??该使用异或吗?
- C/java语言 利用异或运算来交换两个变量的值
- 异或操作交换两个变量的值
- 利用异或,仅使用两个变量进行交换
- 使用异或运算交换两个变量的危险
- 应用位异或交换两个变量的值
- 使用异或运算对交换两个变量的数据
- 位运算的异或来交换变量
- Linux C++编译运行过程
- C++ WINDOWS API 第1章 Windows 应用程序开发入门
- 公众平台测试帐号开发全流程第5篇-消息
- 字体编辑器BMFont
- HDU 3183.A Magic Lamp【RMQ】【4月18】
- 用异或来交换两个变量更耗时
- shell并发处理脚本
- 最小生成树--prim算法
- 【旧版2016.4.17前】东北大学校园网一键登陆ajax版
- 遍历存储卡
- C++ WINDOWS API 第2章 Windows API概要
- HDU 4426Palindromic Substring
- CodeForces 660B Seating On Bus
- 将第三方apk编译进Android系统文件system.img