C语言中异或赋值运算符^=实现数组反转的原理是什么?
异或实现数组反转的底层逻辑
首先你得先明确异或运算的三个基础性质:
- 任意数值和自身异或结果为0:
a ^ a = 0 - 任意数值和0异或结果为自身:
a ^ 0 = a - 异或满足交换律、结合律:
a ^ b = b ^ a、(a ^ b) ^ c = a ^ (b ^ c)
这段代码的核心是用异或运算实现两个变量的无临时变量交换,外层循环只是对称取数组左右两端的元素做交换,循环到中间就完成了整个数组的反转。
我们把循环里的连写赋值拆解来看,^=是右结合运算符,运算顺序从右向左执行。假设当前 a[i] = x、a[j] = y,我们一步步看执行过程:
- 第一步执行最右侧的
a[i] ^= a[j],等价于a[i] = a[i] ^ a[j] = x ^ y,此时a[i]的值为x^y,a[j]的值仍为y - 第二步执行中间的
a[j] ^= a[i],等价于a[j] = a[j] ^ a[i] = y ^ (x ^ y) = x ^ (y ^ y) = x ^ 0 = x,此时a[j]已经被赋值为原来的x,a[i]的值仍为x^y - 第三步执行最左侧的
a[i] ^= a[j],等价于a[i] = a[i] ^ a[j] = (x ^ y) ^ x = y ^ (x ^ x) = y ^ 0 = y,此时a[i]被赋值为原来的y
三步执行完之后,a[i]和a[j]的值就完成了交换,不需要额外定义临时变量存储中间值。
额外提示:这种写法实际不推荐使用,一是可读性非常差,二是如果两个操作数指向同一块内存地址(比如
i==j时)会直接把值清0,三是这种连写赋值在C标准中属于未定义行为,只是大部分编译器兼容了这种写法,实际开发中用临时变量交换的写法可读性、可维护性都更好,现代编译器也会做优化,执行效率不会比异或交换低。
内容的提问来源于stack exchange,提问作者EmreAkkoc
相关产品推荐
相关产品推荐

