[这是我对一位询问如何不使用第三个对象交换两个值的人的回复的一部分。]
发件人:scs@eskimo.com (Steve Summit)
主题:回复:交换两个值
日期:1997年6月13日 07:27:59 -0700 (PDT)
消息ID:<199706131427.HAA06631@mail.eskimo.com>
你写道
> 我有个问题问你
> 我需要交换两个标量的值,而不使用第三个对象。
你问我这个问题可能有两个原因
1. 这个要求是你工作项目的一部分。
2. 这是一个家庭作业或考试题。
如果是前者,请回去说服提出这个要求的建筑师或经理重新考虑。不使用临时变量交换值的技巧只在汇编语言中有用,当寄存器供应不足时。这种技巧在 C 这样的高级语言中没有用武之地,因为临时变量几乎是免费的。如果你使用 C,交换两个值的正确方法是a和b使用一个临时变量t:
t = a; a = b; b = t;
使用这个技巧只会让你的程序稍微大一点、稍微慢一点、稍微难理解一点。
如果是后者,我通常不会给人们家庭作业的答案,但既然这个问题不妥,我很乐意破例。
如果a和b是整数,你可以通过使用这一组有趣的异或操作来交换它们
a ^= b; b ^= a; a ^= b;
但这只在以下情况下有效a和b是整数,并且它有一个额外的缺点,那就是,如果出于某种原因,你有一个指向你要交换的整数的指针,以至于你倾向于写
*p1 ^= *p2; *p2 ^= *p1; *p1 ^= *p2;
那么在以下情况下p1 == p2你将把两者都归零*p1和*p2。(这种情况可能会在以下情况下出现,例如你写
swap(&a[i], &b[j]);在排序例程的上下文中,并且i==j.)
如果a和b是浮点变量,我认为有一些三重的加法和减法序列可以完成交换,但它们都容易发生溢出。
同样,这些“技巧”,即使它们有效,也可能比使用临时变量的明显的三次赋值交换慢得多、庞大得多。这些技巧只是智力上的奇闻;它们不像更明显的交换那样具有任何优势;它们在现代编程中几乎没有用武之地。
如果这确实是一个家庭作业问题,请要求您的讲师将来不要布置它。它基本上是无意义和误导性的;它主要用于诱导学生在实际程序中使用这些技巧,而这些技巧在实际程序中毫无用处。此外,如果您的讲师为这个问题提供的解决方案是以下形式的异或技巧
a ^= b ^= a ^= b;请告知您的讲师,这个表达式在 C 语言中是未定义的。
Steve Summit