C语言中交换两个整数的值之传值调用和传址调用

       在C语言中,一说到交换两个整数的值,大家第一反应可能是这样的代码。定义一个第三方变量来辅助交换。
#include<stdio.h>
int main()
{
    int num1 = 10;
    int num2 = 20;
    int tmp = 0;
    tmp = num1;
    num1 = num2;
    num2 = tmp;
    printf("num1 = %d num2 = %d\n",num1,num2);
    return 0;
}

       这个运行结果我就不拿出来了,他是符合我们预期结果的。那么,如果要求,不允许定义第三变量交换两个整数的值,你会怎么做呢?
       那有些人可能会说,不定义第三变量,可以啊,我在主函数外部再写一个Swap交换函数,通过调用函数来交换两个数的值嘛!于是,就有了这样的代码
#include<stdio.h>
int main()
{
    int num1 = 10;
    int num2 = 20;
    int Swap(int x,int y);
    Swap(num1,num2);
    printf("num1 = %d num2 = %d\n",num1,num2);
    return 0;
}
int Swap(int x,int y)
{
    int tmp;
    tmp = x;
    x = y;
    y = tmp;
    return 0;
}

      那么我们来看一下运行结果
       

       显然这个函数并没有达到预期的效果,那么问题来了,这是为什么呢?我明明调用了这个函数呀,怎么就没有交换数值呢?
       这个问题我们先放下,我们先来看一下程序运行过程以及数值和内存的变化情况
       
       我们可以看到,我们在调用交换函数的时候,主函数中定义的两个整数num1和num2的值的确传给了函数的参数x和y,但是,num1和num2的地址与x和y的地址是没有关联的,这说明num1和num2给Swap函数提供的是当前这两个变量的值的一份临时拷贝,当这两个变量当前的值被函数调用的时候,这两个变量就与函数没有关系了。
       接下来,函数内部的程序一行行运行结束之后
       
       我们可以看到函数内部的x和y的值交换了。
       再跳回到主函数进行输出,这个时候输出的num1与num2依旧是主函数中被赋给的值,即传给函数形参的值,而不是通过函数运行之后的值,所以这个代码没有输出我们预期的结果。
       这也就是我们常说的传值调用。
       经过修改之后,我们又写出了这样得代码
#include<stdio.h>
int main()
{
    int num1 = 10;
    int num2 = 20;
    int Swap(int *x,int *y);
    Swap(&num1,&num2);
    printf("num1 = %d num2 = %d\n",num1,num2);
    return 0;
}
int Swap(int *x,int *y)
{
    int tmp = 0;
    tmp = *x;
    *x = *y;
    *y = tmp;
    return 0;
}

       我们先来看一下运行结果
       
      毫无疑问,这个结果实现了我们的期望值。我们再来看一下内存地址的情况
      
      这里我们可以看到,num1与num2的地址和x与y的地址相同,也就是说,在调用num1和num2这两个变量的值的时候,我们通过调用这两个变量的地址来引用其地址里存放的值,这个时候进入到函数内部,把x地址里的值赋给变量tmp,把y地址里的值赋给x,再把tmp的值赋给y,也就是说把x地址里的值放到了y地址里,把y地址里的值放到x地址里,然后返回到主函数中,因为num1与x的地址相同而num2与y的地址相同,所以当x与y的值变了的时候,num1与num2的值也发生了变化,于是输出结果也就是我们所预期的交换后的值。这就是传址调用。
      说到这里,也许有人又有问题了,你不是说不允许定义第三变量吗?调用的交换函数里定义的tmp不就是第三变量嘛?
       好啦好啦。我的错啦。这回真的不定义第三变量了。提供两种方法
       第一,加减法运算
             num1=num1+num2
             num2=num1-num2
             num1=num1-num2
#include<stdio.h>
int main()
{
    int num1 = 35;
    int num2 = 20;
    num1 = num1+num2;
    num2 = num1-num2;
    num1 = num1-num2;
    printf("num1 = %d num2 = %d\n",num1,num2);
    return 0;
}

      第二,异或运算
      首先,我来给大家介绍一下异或运算。相异为1,相同为0。比如3和5异或,即                011^101,
                   011----->3
                   101----->5
                   异或之后
                   110----->6
                   101
                   异或之后
                   011------>3
                   110
                   异或之后
                   101------>5
       我们可以发现两个数与这两个数异或的结果,这三个数每两两异或,结果都是第三个数。于是这个代码就写出来了
#include<stdio.h>
int main()
{
    int num1 = 10;
    int num2 = 20;
    num1 = num1^num2;
    num2 = num1^num2;
    num1 = num1^num2;
    printf("num1 = %d num2 = %d\n",num1,num2);
    return 0;
}
      这两个程序结果都是正确的。如期的交换了两个变量的值。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值