如何不使用第三个变量进行数据交换?

本文介绍两种不使用额外变量实现两个整数交换的方法:一是利用位运算中的异或操作,二是采用加减法。其中,异或方法更高效但需注意不可对同一变量操作;加减法则易理解但可能导致溢出。

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

对于这个问题又两种方法

第一种通过按位异或实现

int a=7,b=5;

a=a^b;

b=a^b;

a=a^b;

最终a=7,b=5,看起来虽然奇怪,但是的确能做到交换的效果,具体过程转换成2进制来看:

a=0111;

b=0101;

a=0111^0101; / / =0010 ,一样的置0,不一样的置1

b=0010^0101; //=0111=7;

a=0010^0111; //=0101=5

交换的过程就是这样,没有什么大的道理,仔细揣摩还是有点意思。

但是用这种方法需要注意一个问题,就是不能拿相同的变量来作交换,意思就是自己不能跟自己交换。听起来会觉得很奇怪,谁没事让一个变量自己跟自己交换呢,下面我说一个我遇到的例子,就是用这种方式来交换数据,结果出bug了,调试了很久才发现的。看代码:

	/**
	 * 交换方法
	 * @param arr
	 * @param i
	 * @param j
	 */
	public static void swap(int[] arr,int i,int j){
		if(i==j){
			return;
		}
		arr[i]=arr[i]^arr[j];
		arr[j]=arr[i]^arr[j];
		arr[i]=arr[i]^arr[j];
	}
	
	public static int partition(int left,int right,int point){
		int leftPtr=left-1;
		int rightPtr=right;
		while(true){
			while(leftPtr<rightPtr&&arr[++leftPtr]<point);
			while(leftPtr<rightPtr&&arr[--rightPtr]>point);
			if(leftPtr==rightPtr){
				break;
			}else{
				swap(arr, leftPtr, rightPtr);
			}
		}
		swap(arr, leftPtr, right);
		return leftPtr;
	}
	
	private static void segmentation(int left, int right) {
		if(left>right){
			return;
		}
		int point =arr[right];
		int partition=partition(left, right, point);
		segmentation(left, partition-1);
		segmentation(partition+1, right);
	}
这是一个快速排序的算法,没写注释,也不必看懂,就注意那个交换数据的方法,在交换之前我加了一句判断,判断给定的索引是不是相等,如果相等的话,那么arr[i]和arr[j]就是同一个东西,他们地址什么的都相同,这个时候他们再交换,结果就是他们都将会被置0,所以出现这种情况,就直接让它返回,不必再作交换,如果没这个判断,这个排序是有问题的。所以举这个例子就是为了说明bug无处不在,需处处小心。

第二种方法就是用加减法交换

int a=12;

int b=15;

a=b-a;

b=b-a;

a=b+a;

这种方法都能看懂,就不多说,这个要注意的就是数据可能会溢出,所以在使用之前要考虑数据范围。

两种方法比较起来,按位与的方式效率略微高一些。

功能块(Function Block,FB)是IEC 61131-3编程标准中用于封装特定功能的模块。在三菱GX IEC Developer中创建和使用功能块,可以提高程序的复用性和模块化程度,这对于复杂PLC程序的开发尤为重要。具体操作步骤如下: 参考资源链接:[三菱GX IEC Developer:从入门到高级编程指南](https://wenku.youkuaiyun.com/doc/7nmmaee9ix?spm=1055.2569.3001.10343) 第一步,打开GX IEC Developer软件,新建或打开一个项目。 第二步,在项目资源管理器中找到“Programs”文件夹,右击选择“New Functional Block”创建一个新的功能块。 第三步,在功能块的编辑界面,定义所需的输入(IN)、输出(OUT)和输入/输出(INOUT)变量。例如,创建一个名为‘FB1’的功能块,它有一个整型的输入变量‘InputVar’和一个输出变量‘OutputVar’。 第四步,在功能块的Body部分编写实现特定功能的逻辑。例如,可以创建一个简单的功能块,将输入变量的值赋给输出变量。代码示例: FUNCTION_BLOCK FB1 VAR_INPUT InputVar : INT; END_VAR VAR_OUTPUT OutputVar : INT; END_VAR VAR END_VAR OutputVar := InputVar; END_FUNCTION_BLOCK 第五步,保存功能块并编译检查无误后,可以在主程序或其他功能块中调用该功能块,并分配局部变量进行数据交换。 第六步,在主程序或其他功能块中声明局部变量,并实例化功能块FB1,设置输入变量的值,并读取输出变量的值进行后续操作。例如: VAR MyFB1 : FB1; // 功能块实例化 LocalInput : INT := 10; // 局部变量赋值 LocalOutput : INT; END_VAR MyFB1.InputVar := LocalInput; // 将局部变量值赋给功能块的输入变量 MyFB1(); // 调用功能块 LocalOutput := MyFB1.OutputVar; // 获取功能块的输出变量值 这样,通过局部变量的赋值和读取,实现了功能块内逻辑的执行以及与主程序或其他功能块间的数据交换。在《三菱GX IEC Developer:从入门到高级编程指南》中,您将找到更多关于功能块创建、变量管理以及程序组织的详细信息,帮助您深入理解和掌握这一过程。 参考资源链接:[三菱GX IEC Developer:从入门到高级编程指南](https://wenku.youkuaiyun.com/doc/7nmmaee9ix?spm=1055.2569.3001.10343)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值