这次我们要透过一个简单的函数swap深入理解函数传参的本质以及在C中如何选择传参方式。

首先,先来看第一段程序:

void swap(int x, int y) {int temp = y;y = x;x = temp;
}

通过main函数的调用,我们发现x,y并未实现交换:

int main()
{int x = 1;int y = 37;swap(x, y);printf("x:%d; y:%d\n",x,y);return 0;
}

【原因解析】:

整形x和y在函数swap内为按值传递,按值传递时,函数不会访问当前调用的实参函数处理的值是它本地的拷贝,这些拷贝被存储在运行栈中,因此改变这些值不会影响实参的值。一旦函数结束了,函数的活动记录将从栈中弹出,这些局部值也就消失了。

在按值传递的情况下,实参的内容没有被改变。这意味着程序员在函数调用时无需保存和恢复实参的值。
如果没有按值传递机制,那么每个没有被声明为const 的参数就可能会随每次函数调用而被改变。按值传递的危害最小,需要用户做的工作也最少。毫无疑问,按值传递是参数传递合理的缺省机制。

另外,如果作为实参的变量是一个大型类的对象,分配并拷贝到栈中的时间和空间开销往往过大。
要实现swap函数的效果,我们应如何处理呢?

第一个可行的做法是将形参声明成指针

void pswap(int *x, int *y) {int temp = *y;*y = *x;    //将x指针所指地址的值 赋值给 y指针所指地址;*x相当于一个整数,将其赋值给指针变量所指的地址*x = temp;
}

在pswap函数中,由于传递的是两个变量的内存地址(指针),使得我们可以直接操作对应的值。实际上这里还是存在按值传递的问题(其实并没对x y本身做了改变,x y仍指向原来的地址,只是地址中的值发生了变化),只是由原先的整形传递变成了指针传递。我们可以修改指针指向的内存却依然无法修改指针本身

第二个可行的做法是将形参声明为指针的引用

void prswap(int *&x, int *&y) {int temp = *y;*y = *x;*x = temp;
}void prswap(int *&x, int *&y) {int *temp = y;y = x;x = temp;
}

请注意,同一个函数原型下我提供了两种函数定义。可无论哪一种,在实参传递的阶段都不会发生按值传递的问题。那么两种定义到底哪一种更满足我们需求:
(1)交换内存中的值

(2)交换指针地址

如果单独考虑本文的需求,第一种方法更满足。但是,如果我们需要交换的是一个大型类对象,第二种的效率则更高。

总结:内存管理是C++学习的一个难点,初学者往往不容易掌握。但越是如此就越能体现一个开发者的语言内功。

转自:https://www.cnblogs.com/learnhow/p/8543822.html

【C语言】交换函数(swap)相关推荐

  1. C语言交换函数:传值函数与传址函数的区别

    1.传址函数典例 想必初识C语言函数的同学会遇到这样的问题: 当你想要写一个交换函数:交换输入的两个数字的值.明明将要传的两个数字传上去了,函数里的交换写法也没有问题,可为什么运行时会错呢?这就牵扯到 ...

  2. 交换函数swap的三种实现方法

    本文采用三种方式实现两个数之间的交换,分别是①借助辅助变量temp的swap函数,②采用加减法的swap函数 ,③使用异或运算的swap函数. 现在直奔主题: 1.借助辅助变量temp的swap函数 ...

  3. (C++)用指针实现两数交换函数swap()的两种方法

    #include<cstdio>//用指针写swap()函数 void swap_1(int* p1,int* p2){int temp = *p1;*p1 = *p2;*p2 = tem ...

  4. Go 语言编程 — 函数

    目录 文章目录 目录 定义一个函数 形参列表 值传递 引用传递 返回值 初始化函数 构造函数 析构函数 回调函数 闭包(Closure)函数 方法函数 递归函数 定义一个函数 函数声明需要指定: 函数 ...

  5. 指针:调用自定义交换函数,完成三个数整从小到大排列

    Description 调用自定义交换函数swap(int *p1, int *p2),完成三个整数从小到大排列 Input 多组测试数据,每组输入三个任意整数 Output 输出从小到大排列的三个数 ...

  6. c语言 swap交换函数_C语言经典100题(14)

    1 上期答案揭晓 首先给大家看看上一篇文章C语言经典100题(13)中第三部分编程题的答案: #includeint main(){ int i,x,y,z; for(i=100;i<1000; ...

  7. C语言中利用Swap函数交换变量a,b

    C语言中利用Swap函数交换变量a,b 常见错误写法 error1 void Sawp_error1(int a,int b) {int tmp;tmp=a;a=b;b=tmp; } int main ...

  8. C++学习笔记(二)——交换函数(swap)

    这次我们要透过一个简单的函数swap深入理解函数传参的本质以及在C++中如何选择传参方式. 先来看第一段程序: void swap(int x, int y) {int temp = y;y = x; ...

  9. Java实现swap交换函数的数组方法

    Java实现swap交换函数的数组方法 public class fun_1 {//定义数组类型的函数static int[] swap(int a,int b){int t =a;a =b;b =t ...

最新文章

  1. Nginx设置静态页面压缩和缓存过期时间的方法 (转)
  2. c #include如何找到文件_如何用C编写自己的头文件?
  3. Java笔试题库之编程题库 总共30道编程题,掌握了就可以应付中级以内Java面试题
  4. 分区表分区字段的update操作
  5. 如何在Mac上用Script启动quicktime录制?
  6. C++ unordered_map初始化
  7. 【分享】“飞鹅打印机“ 在集简云平台集成应用的常见问题与解决方案
  8. 基于51单片机+LCD1602显示
  9. 破解Kindle,轻松自定义字体
  10. Himawari8注册后发来信息下载数据
  11. OSC802 USB虚拟示波器开箱与测评
  12. 【自学Python:Day2】磨洋工的我一周一课……
  13. TLC5615 10位DA模块数模转换芯片驱动
  14. android 指纹比对方法,指纹识别功能方面对比_手机Android频道-中关村在线
  15. jQuery全选全删动态表格
  16. 最美的时候你遇见了谁
  17. MyBatis在Spring中的事务管理
  18. 传奇GOM引擎登陆器配置教程 GOM登陆器配置详解 GOM引擎登陆器图文教程
  19. CleanMyMac X激活码免费版安装包MAC清理工具
  20. php提取文章图片作缩略图,Wordpress自动提取文章内第一张图作为缩略图方法 | WordPress指南...

热门文章

  1. 10大PPT模板可直接套用助PM正确写好年终总结
  2. 建设工程项目全寿命周期管理是指_工程项目全寿命周期管理.ppt
  3. jsp70860基于web的大学教室管理系统
  4. 校园二手商城小程序,手把手带你开发一款云开发版商城小程序,校园二手微信小程序,可升级社区团购小程序
  5. im即时通讯开发:聊天消息的同步和存储
  6. 成都Java程序员培训毕业后什么水平
  7. 简单工厂(静态工厂)
  8. 企业级开发平台的演进
  9. Java通过javacsv实现读取csv文件数据
  10. 我们问了人工智能ChatGPT十个运维问题,结果发现...