在我们编写程序时,大多数情况下都是函数传参,接收返回参数,但这中间有一定的操作系统内存传递原理,当你看完这篇文章你会发现,噢!原来这样使用会出错之类的感想!

最简单的,函数现场保护,通常操作系统会使用call指令来调用函数,用ret返回上一个函数,中间需要将上一个函数的执行情况,以及返回地址写入到寄存器(根据架构不同看CPU如何选择寄存器)当中,供ret指令使用!

考虑到看这篇文章的都是刚入门级别的所以就不从汇编角度来分析了!也不分析汇编代码之类的,这里就从最上层的术语讲解!

一.函数调用

int add(int c){c = c+1;return c;
}int main(){int y = add(2);
}

以上有add函数,add函数负责将传递进来的值+1

当我们调用add函数时,如果给定的是立即数(也就是常数123456但不是变量)那么立即数会被放入代码段的低位则本身不开辟地址空间,比如01010001前面0101000是函数传参,后面的01二进制到十进制就是1那么就是将01传递给参数!

如果不是立即数,是变量,比如:

int add(int c){c = c+1;return c;
}int main(){int i = 2;int y = add(i);
}

那么就会使用寻址汇编指令先将i的地址里的值取出放入到临时通用寄存器(看架构)里在将值写入到参数内存里去

小知识:

CPU不可以直接写入,因为内存单元不归CPU管控,CPU只能先取出来值,然后在告诉内存芯片这个值应该给谁,由内存芯片来做

二. 线程传参

线程A
int add(int* c){
for(int i = 0;i<=10000;++i);    //sleepc = c+1;return c;
}
线程B
int add1(){int c = 0;add(&c);return c;
}

这个函数看起来没有什么问题,但会中断

原因:

在线程传参时一般参数是指针(操作系统规范) 指针指向值,如果这个时候b线程给a线程的是栈数据(如果双方时间轴不同),那么b线程结束掉了,b线程的栈内存被回收了,而a线程里的指针指向b线程,这时a线程操作指针就会出现地址非法,所以我们应该注意,在传参时一定要使用malloc来分配一个内存,然后写入值,在将地址传递给下一个指针就可以了!

当然加锁也是一种解决办法

注意int*和其他类型可以使用memcpy函数来copy

memcpy(a,b,sizeof(int));//将int b 的值copy给a

传递好了之后在指针指向就可以了

int *a = malloc

memcpy..

int *b = *a; //解引用将a指向的值返回回来

str可以使用strcpy!

三. 指针返回参数

int *add(int a, int b){int size = a+b;return size;
}int main(){int *Size = add(2,3);    printf("%d",Size);
}

输出:

随机值

原因:

add函数返回的是指针类型的,而非栈类型,编译器在返回时会返回size的地址,而add函数里的size恰巧是栈类型,所以在return前此内存就会被释放,原因:栈返回类型时:return时CPU会把值取出放入寄存器在带回,而返回地址时,内存恰巧被释放了,乱内存,所以Size指向的是被释放的内存段乱地址!

C/C++语言传参、返回参数知识点讲解相关推荐

  1. springboot接口入参下划线转驼峰以及返回参数驼峰转下划线实现

    转自:springboot接口入参下划线转驼峰以及返回参数驼峰转下划线实现 - 李东平|一线码农 - 博客园 (cnblogs.com) 1.背景 在实际开发中,通常来说java里面是使用驼峰的命名规 ...

  2. 几何算法——5.关于ACIS和Parasolid求交的调研以及返回参数设计

    关于ACIS和Parasolid求交的调研以及返回参数设计 1. Parasolid求交 1.1 曲线/曲线交点(CCI) 1.1.1 接口 1.1.2 交点类型 1.1.3 错误类型 1.1.5 o ...

  3. url传参 获取参数方法

    url传参 获取参数方法 //调用const infos = this.getQuery(); //该方法返回一个对象 key 为所传参数名 value 参数值getQuery(key) {var s ...

  4. 函数使用(函数定义及调用方式、传参与返回参数、命名空间、装饰器)

    函数定义及调用方式 一. 定义函数 1. 自定义函数的规则 • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ().     • 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以 ...

  5. java 调用webservice 接口,并解析返回参数

    java 调用webservice 接口,并解析返回参数 1. 设置传参,例如以下格式: // 确定传参格式以及赋值 String reqXml = "<createAppParam& ...

  6. 关于Scala递归返回参数的问题

    Scala的递归返回参数要自己写,因为他看最后一行代码可能陷进死循环里,退出条件不在一行,所以返回类型要自己确定 转载于:https://www.cnblogs.com/sunpengblog/p/1 ...

  7. 【报错笔记】在maven项目中jsp页面使用window.location.href给controller传参时参数过长所以路径无法跳转至controller

    在maven项目中jsp页面使用window.location.href给controller传参时参数过长所以路径无法跳转至controller 解决方案:使用a链接来用

  8. XGBoost-Python完全调参指南-参数解释篇

    本文转自XGBoost-Python完全调参指南-参数解释篇.对XGBoost有需要小伙伴可以参看.并在此基础上,添加了一些内容. 在analytics vidhya上看到一篇<Complete ...

  9. ajax 与route的区别,浅析vue-router jquery和params传参(接收参数)$router $route的区别

    今天做项目时踩到了vue-router传参的坑(jquery和params),所以决定总结一下二者的区别. 1.jquery方式传参和接收参数 传参: this.$router.push({ path ...

最新文章

  1. CTFshow 反序列化 web269
  2. linux服务器都有注册表吗,NT服务器的注册表结构介绍
  3. WannaCry勒索比特币蠕虫病毒解决方案
  4. C++string容器应用举例
  5. matlab weibpdf函数,matlab建模常用函数
  6. Linux基础学习五:软件的相关安装(JDK,Tomcat,Yum)
  7. LCS-最大公共子序列(DP问题)
  8. 大数据-03-Spark入门
  9. jQuery插件——自定义jQuery插件
  10. VLC框架总结(一)VLC源码及各modules功能介绍
  11. postmessage传递字符串_postMessage 还能这样玩
  12. Win10最美SSH工具
  13. Android App加壳中的整体dex加壳的原理和脱壳
  14. 中国大学慕课python答案 北京理工大学_中国大学慕课mooc_Python 语言程序设计_章节测验答案...
  15. 前端在登录时如何将用户密码加密
  16. python判断对错题_Python爬虫自动化获取华图和粉笔网站的错题(推荐)
  17. 大写字母逆序2 (100分)
  18. Revit插件建模助手尺寸定位标注和标注避让操作
  19. 浅谈Thread.setDaemon
  20. Netty 源码分析系列(十五)自定义解码器、编码器、编解码器

热门文章

  1. 如何测试判断云服务器的稳定性?
  2. seqkit根据基因id_ID转换靠的是深厚的背景知识加上一点代码技巧
  3. 微信小程序中识别html标签的方法
  4. 进阶05 常用数据结构
  5. php语句创建数据表,用mysql语句创建数据表详细教程
  6. 创建ServerSocket出错Permission denied
  7. 查看mysql的默认存储引擎信息_如何查看mysql的默认存储引擎
  8. android 分包粘包_Android Socket 发送与接收数据问题处理: 发送后的数据接收到总是粘包...
  9. vscode 5500 but failed to open in Browser Preview. Got Browser Preview extension installed?
  10. JavaEE系统架构师学习路线