异或交换仅适用于整数且要求a、b为不同变量;其原理基于自反性(x^x==0)、恒等性(x^0==x)和交换结合律,三步操作可逆推保证信息不丢失,但实际工程中无性能优势,仅适用于嵌入式或教学场景。

能交换,但只适用于整数,且 a 和 b 不能是同一变量(比如 &a == &b)——否则三步之后全变 0。
为什么异或能交换:关键就靠三条代数性质
异或交换不是黑魔法,它完全依赖三个确定的数学事实:
-
x ^ x == 0(自反性) -
x ^ 0 == x(恒等性) -
a ^ b == b ^ a且(a ^ b) ^ c == a ^ (b ^ c)(交换律 + 结合律)
这三条保证了三步操作中信息不丢失、可逆推。例如初始 a = 5, b = 10:
a = a ^ b; // a 变成 5 ^ 10 b = a ^ b; // 相当于 (5 ^ 10) ^ 10 → 5 ^ (10 ^ 10) → 5 ^ 0 → 5 a = a ^ b; // 相当于 (5 ^ 10) ^ 5 → 10 ^ (5 ^ 5) → 10 ^ 0 → 10
注意:每一步都依赖上一步的结果,顺序不能错;也不能写成宏或函数里直接传 a, b 值参——必须是可修改的左值。
实际写法与常见翻车点
最简写法就是连续三行赋值:
int a = 7, b = 13; a = a ^ b; b = a ^ b; a = a ^ b;
但容易出错的地方有这些:
- 用在指针解引用时,若
p和q指向同一地址,*p = *p ^ *q后变成 0,后续全崩 - 写成宏:
#define SWAP(a,b) a^=b;b^=a;a^=b—— 若调用SWAP(x, x),结果是未定义行为 - 误用于浮点数:
float或double不能直接异或,编译不过(位运算只对整型有效) - 和加减法混用:有人记串成
a += b; b -= a; a -= b;,这会出负数甚至溢出,不是等价替换
比起临时变量,它真有优势吗?
现代编译器(GCC/Clang/MSVC)在 -O2 及以上优化等级下,对 int temp = a; a = b; b = temp; 通常生成完全相同的汇编指令——寄存器重命名搞定一切,根本不占额外内存。
所以它的“优势”只剩两个真实场景:
- 裸机/嵌入式环境,你手写汇编或需要精确控制寄存器分配
- 教学或面试中考察对位运算本质的理解,而非工程实践
日常代码里硬套 a ^= b ^= a ^= b; 这种写法,不仅可读性差,还违反序列点规则(C 标准中是未定义行为),千万别这么写。
真正容易被忽略的是:它不解决任何现代编程中的性能瓶颈,反而可能因掩盖意图而拖慢协作效率。用就用,但得清楚——你换的不是数值,是别人读懂你代码的时间。










