【C/C++】异或操作巧妙实现两个数的交换操作

本文详细解析了OpenGL加载TGA格式图像时,如何使用位异或操作实现RGB(A)顺序的交换,解释了该操作背后的原理,并通过实验对比了其与传统方法的性能差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在看OpenGL加载TGA格式图像用作纹理的代码时,看到关于RGB(A)顺序转换的一行代码时,捉一开始感到很困惑,后来想了想,就是实现交换操作。

原始代码:

texture->imageData[cswap] ^= texture->imageData[cswap+2] ^=
texture->imageData[cswap] ^= texture->imageData[cswap+2];
写了一段代码测试了一下:

#include <iostream>

using namespace std;

int main()
{
	int a = 1;
	int b = 2;
	a ^= b ^= a ^= b;
	cout << "a = " <<a << endl;
	cout << "b = " <<b << endl;
}
运行结果:

^ 在 C 里面是按位异或操作符,相同的话异或的结果就是 0,不同的话就是 1。

其实用笔推一下就知道了。

首先,运算顺序是从右往左的。

假设a、b原始值记为a0,b0.

最右边的^=运算之后:

b不变。b = b0.

a = a0 ^ b0;

倒数第二个^=运算之后:

a不变。a = a0 ^ b0;

b = b0 ^ a = b0 ^ (a0 ^ b0) = b0 ^ (b0 ^ a0) = a0;

最前面的^=运算之后:

b不变。b= a0;

a = a ^ b = (a0 ^ b0) ^ a0 = b0.

这样就实现了a和b两个数的交换操作。


说实话,第一次见到这样的语句时,确实很费解。诚然,这样的操作相比声明一个临时变量,节省空间。但是感觉代码的可读性并不是很好。


我看到原始代码这条语句上还有一个注释,说是XX优化的。

但是我写了一个程序测试了一下,异或操作方法好像还要慢一些。

#include <iostream>
#include <time.h>
#include <windows.h>

using namespace std;

int main()
{
	int a = 1;
	int b = 2;
	
	int temp = 0;
	DWORD time1 = GetTickCount();
	cout << "time1 = " << time1 << endl;
	for (int i = 0;i < 100000000;++i)
	{
		//a ^= b ^= a ^= b;
		temp = a;
		a = b;
		b = temp;
	}

	DWORD time2 = GetTickCount();
	cout << "time2 = " << time2 << endl;
	cout << time2 - time1 << endl;
}
普通方法:

异或方法:



个人感觉还是用普通的方法好点。路过的给点建议哈~~


C++ 中,可以通过多种方式实现交换个整数的值。以下是几种常见的方法及其具体实现: ### 方法一:通过引用传递参数 这是最常见的方式之一,在函数内部直接操作原始变量,而不需要额外的空间存储临时变量。 ```cpp #include <iostream> using namespace std; // 使用引用交换个整数 void swapByReference(int& a, int& b) { int temp = a; // 将a的值赋给temp a = b; // 将b的值赋给a b = temp; // 将temp(即原来的a)赋给b[^1] } int main() { int x = 5, y = 10; cout << "Before swapping: x=" << x << ", y=" << y << endl; swapByReference(x, y); cout << "After swapping: x=" << x << ", y=" << y << endl; return 0; } ``` --- ### 方法二:使用标准库中的 `std::swap` 函数 C++ 提供了内置的标准库函数 `std::swap` 来简化交换过程,这种方式更加简洁高效,并且适用于各种数据类型。 ```cpp #include <iostream> #include <algorithm> // 包含std::swap声明 using namespace std; int main() { int left = 5, right = 10; cout << "Before swapping: left=" << left << ", right=" << right << endl; std::swap(left, right); // 调用标准库函数进行交换[^2] cout << "After swapping: left=" << left << ", right=" << right << endl; return 0; } ``` --- ### 方法三:通过指针传递参数 该方法涉及解引用指针来访问并修改实际内存地址上的值。尽管这种方法较为复杂,但在某些场景下可能更灵活。 ```cpp #include <iostream> using namespace std; // 使用指针交换个整数 void swapByPointer(int* xp, int* yp) { int temp = *xp; // 解引用获取xp指向的实际值 *xp = *yp; // 修改xp所指向位置的值为yp的值 *yp = temp; // 修改yp所指向位置的值为保存下来的旧xp值[^5] } int main() { int x = 5, y = 10; cout << "Before swapping: x=" << x << ", y=" << y << endl; swapByPointer(&x, &y); // 传入变量的地址 cout << "After swapping: x=" << x << ", y=" << y << endl; return 0; } ``` --- ### 方法四:算术运算法(加减法) 这种技术利用基本数学原理完成交换,无需借助中间变量。然而需要注意的是,当参与交换的数值过大时可能会引发溢出问题。 ```cpp #include <iostream> using namespace std; // 利用加减法交换个整数 void arithmeticSwap(int* xp, int* yp) { *xp = *xp + *yp; // 增大第一个数等于者之和 *yp = *xp - *yp; // 计算第二个新值应为原差额 *xp = *xp - *yp; // 还原第一个新值为原来第二者的值[^5] } int main() { int x = 5, y = 10; cout << "Before swapping: x=" << x << ", y=" << y << endl; arithmeticSwap(&x, &y); cout << "After swapping: x=" << x << ", y=" << y << endl; return 0; } ``` 注意:由于存在潜在的数据溢出风险,因此推荐谨慎选用此类算法。 --- ### 方法五:位运算异或法 这是一种巧妙的技术手段,它基于 XOR 的特性实现了无辅助空间下的互换逻辑。不过同样要注意其局限性和适用条件。 ```cpp #include <iostream> using namespace std; // 使用XOR位运算交换个整数 void xorSwap(int* xp, int* yp) { if (*xp != *yp) { // 避免相同值情况下的未定义行为 *xp ^= *yp; // 第一步:执行第一次异或操作 *yp ^= *xp ^ *yp; // 第二步:恢复初始状态的同时更新目标值 *xp ^= *yp; // 第三步:最终得到期望的结果 } } int main() { int x = 5, y = 10; cout << "Before swapping: x=" << x << ", y=" << y << endl; xorSwap(&x, &y); cout << "After swapping: x=" << x << ", y=" << y << endl; return 0; } ``` --- ####
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

没有昵称阿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值