C++程序设计——十四

使用C语言实现两数交换

对于两个整型变量a和b,假设a=3,b=4,我们怎么实现交换它们的值呢?

预备知识:*符号和&符号

在C语言中,*除了代表乘法运算,还代表指针运算,&代表取地址操作。*后面必须跟指针变量,而&则无特殊要求。
什么是指针?指针其实就是指内存地址,而指针变量就是用来存储内存地址的变量,即这个指针变量的值即为一个内存地址。
我们来看一个示例

#include <stdio.h>

int main()
{
    int x=123;

    int *p;//定义一个整型指针变量,p用来存储一个整型变量的地址
    p=&x;
    printf("变量x的地址即p的值为:%d\n",p);
    printf("&x=%d\n",&x);
    printf("*p=%d\n",*p);
    return 0;
}

输出如下

变量x的地址即p的值为:-9876
&x=-9876
*p=123

前面两个输出毫无疑问,但是为什么*p=123呢。因为在C语言中,我们int *p;来表示生成一个指针变量p,p的值就是指针变量存储的地址,p就代表这个地址上对应的数据,因为变量x的值为123,它存储在存储单元-9876里面,那么输出p就代表输出存储单元-9876上的值123.

实现两数交换

接下来我们就用指针变量和&取地址符实现两数交换,直接上代码

#include <stdio.h>

void swap1(int *a,int *b)
{
    int tmp=*a;
    *a=*b;
    *b=tmp;
}

void swap2(int *a,int *b)
{
    *a=*a+*b;
    *b=*a-*b;
    *a=*a-*b;
}

void swap3(int *a,int *b)
{
    *a=(*a)^(*b);
    *b=(*a)^(*b);
    *a=(*a)^(*b);
}

void swap4(int *a,int *b)
{
    *a=*a+*b-(*b=*a);
}

int main()
{
    int a=3;
    int b=4;
    swap1(&a,&b);
    printf("a:%d,b:%d\n",a,b);
    swap2(&a,&b);
    printf("a:%d,b:%d\n",a,b);
    swap3(&a,&b);
    printf("a:%d,b:%d\n",a,b);
    swap4(&a,&b);
    printf("a:%d,b:%d\n",a,b);
    return 0;
}

运行结果如下

a:4,b:3
a:3,b:4
a:4,b:3
a:3,b:4

下面我们来一一讲解着四个实现两数交换的函数

swap1

在swap1函数中,我们传入的实参为两个变量的地址,那么在函数中自然需要两个指针变量来作为形参存储地址,所以使用函数时对变量应用取地址符号&,而函数形参那里为指针变量,其实这是实现两数交换的基础(四个swap函数皆是如此),只有这样,我们传入main函数里变量的地址,才能对其实现值的变化,否则只传入值,会造成在swap函数中生成临时变量,对临时变量的操作不会影响main函数中的变量的值。
在这个函数中,我们通过一个临时整型变量tmp先存储指针变量a对应内存单元上存储的值,再把指针变量b对应内存单元上的值赋给a,即把指针变量a对应内存单元上的值变为4,再把tmp存储的最开始a的值3赋给*b,这样就实现了两数交换。

swap2

就是通过加减法实现两数交换,不过这个不容易想到。

swap3

通过计算机异或操作实现两数交换。
我们知道,在二进制中,1和0异或得到1,1和1异或得到0,0和0异或得到0,即恰好只有一个为真时才为真。
又因为数字在计算机中是按二进制进行计算的,通过这个原理,我们就可以实现两数交换。

swap3的3次异或计算过程如下:
——————————————
0011–>a最初
0100–>b最初
——————
0111–>a(第一次异或的值赋给a)
0100–>b
——————
0011–>b(第二次异或的值赋给b)
0111–>a
——————
0100–>a(第三次异或的值赋给a)
———————————————
经过三次异或操作,a由0011即3变为0100,b由0100即4变为0011

swap4

在我的理解中,函数4巧妙利用了缓冲区的机制
对式子*a=*a+*b-(*b=*a),先计算(*b=*a),但是计算结果留在缓冲区,没有改变内存单元中*b的值,然后计算*a=*a+*b-*a,这里的*b仍是从内存单元中取值,这时,在缓冲区中,有*a=3*b=4,再赋值到内存单元上,实现了两数交换

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值