(常考)交换两个变量的值,而不使用第三变量的方法总结

本文深入探讨了C语言中不使用额外变量进行变量值交换的五种方法:算术运算法、位运算、指针地址操作、升级的xor算法及栈实现。详细解析了每种方法的工作原理和适用场景。

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

我们在刚学C语言时,做两个变量的交换时,常常借助第三变量。其原始代码如下:

0)原始方法

int a ,b ,t;
a =6 ;
b=9 ;
t = a ;
a = b ;
b = t ;

这个算法最大的缺点就是借用了临时变量。
那么,我们看看不借助临时变量的交换算法有哪些:

1)算术运算法

int a, b ;
a = 6 ;
b = 9 ;
a = a + b ; //a = 15
b = a - b ; // b =6 , a =15
a = a -b ; // b = 6 ,a = 9

这个我们容易想到

2) 位运算

int a = 3;  // a = 0011
int b = 4;  // b = 0100
a = a^b; // a = 0011^0100 = 0111
b = a^b; // b = 0111^0100 = 0011=3
a = a^b; // a = 0111 ^  0011= 0100 =4

此算法能够实现是由异或运算的特点决定的,通过异或运算能够使数据中的某些位翻转,其他位不变。这就意味着任意一个数与任意一个给定的值连续异或两次,值不变,(理论上重载“^”运算符,也可以实现任意结构的交换)

3)指针地址操作
因为对地址的操作实际上进行的是整数运算,比如:两个地址相减得到一个整数,表示两个变量在内存中的储存位置隔了多少个字节;地址和一个整数相加即“a+10”表示以a为基地址的在a后10个a类数据单元的地址。所以理论上可以通过和算术算法类似的运算来完成地址的交换,从而达到交换变量的目的。即:

int*a,*b;
*a=newint(10);
*b=newint(20);//&a=0x00001000h,&b=0x00001200h
a=(int*)(b-a);//&a=0x00000200h,&b=0x00001200h
b=(int*)(b-a);//&a=0x00000200h,&b=0x00001000h
a=(int*)(b+int(a));//&a=0x00001200h,&b=0x00001000h

4)升级的xor算法

#include <stdio.h>

void xorSwap (int* x, int* y) {
    if (x != y) { //ensure that memory locations are different
       *x ^= *y;
       *y ^= *x;
       *x ^= *y;
    }}

int main(void) { 
    int a = 3; 
    int b = 4; 
    xorSwap(&a,&b);
     
    printf("%d,%d\n",a,b);
	return 0;
}

测试是为了确保x和y具有不同的内存位置(而不是不同的值)。这是因为(p xor p) = 0如果x和y共享相同的内存位置,当一个设置为0时,两者都设置为0.当* x和* y都为0时,* x和* y上的所有其他xor操作将相等0(因为它们是相同的),这意味着该函数将* x和* y都设置为0。

5)栈实现。不多解释了,栈和相关函数定义省去

intexchange(intx,inty)
{
stack S;
push(S,x);
push(S,y);
x=pop(S);
y=pop(S);
}

总结一下:
以上算法均实现了不借助其他变量来完成两个变量值的交换,相比较而言算术算法和位算法计算量相当,地址算法中计算较复杂,却可以很轻松的实现大类型(比如自定义的类或结构)的交换,而前两种只能进行整形数据的交换(理论上重载“^”运算符,也可以实现任意结构的交换)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值