目录

形参和实参:

形参和实参关系:

实参为值传值

实参为指针传值

实参本身为普通变量

实参本身为指针

一级指针

二级指针

引用传值


形参和实参:

什么是形参(parameter),什么是实参(argument)

在函数定义中出现的参数可以看做是一个占位符,它没有数据,只能等到函数被调用时接收传递进来的数据,所以称为形式参数,简称形参

给形参传递值的变量称为实际参数,简称实参

形参和实参关系:

1) 形参变量只有在函数被调用时才会分配内存,调用结束后,立刻释放内存,所以形参变量只有在函数内部有效,不能在函数外部使用。

2) 实参可以是常量、变量、表达式、函数等,无论实参是何种类型的数据,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参,所以应该提前用赋值、输入等办法使实参获得确定值。

3) 实参和形参在数量上、类型上、顺序上必须严格一致,否则会发生“类型不匹配”的错误。当然,如果能够进行自动类型转换,或者进行了强制类型转换,那么实参类型也可以不同于形参类型。

实参为值传值

代码:

#include<iostream>
using namespace std;
void swap(int a,int b)
{cout<<"a address1 = "<<&a<<endl;cout<<"b address1 = "<<&b<<endl;int temp = a;a = b;b = temp;
}int main()
{int a = 10;int b = 20;cout<<"a address = "<<&a<<endl;cout<<"b address = "<<&b<<endl;cout<<"original "<<"a = "<<a<<" b="<<b<<endl;swap(a,b);cout<<"swaped "<<"a = "<<a<<" b="<<b<<endl;return 0;
}

执行结果:

分析结果:

实参a,b 和形参a,b的地址是不一样的,因为形参a,b是整型变量,他们在函数调用时分配内存,里面只是存放了和实参对应得整型值,所以改变形参变量a,b的值并没有改变实参a,b的值。形参a,b是临时变量,当函数运行结束时,他们的生命周期也就结束了。所以实参a,b的值并没有改变。

图解:

实参为指针传值

实参本身为普通变量

代码:

#include<iostream>
using namespace std;
void swap(int *a,int *b)
{cout<<"parameter a address1 = "<<&a<<endl;cout<<"parameter b address1 = "<<&b<<endl;cout<<"a value address1 = "<<a<<endl;cout<<"b value address1 = "<<b<<endl;int temp = *a;*a = *b;*b = temp;
}int main()
{int a = 10;int b = 20;cout<<"a address = "<<&a<<endl;cout<<"b address = "<<&b<<endl;cout<<"original "<<"a = "<<a<<" b="<<b<<endl;swap(&a,&b);cout<<"swap "<<"a = "<<a<<" b="<<b<<endl;return 0;
}

执行结果:

分析结果:

*p 指的是 指针变量p所指向的地址所存放的内容

&p指的是指针本身的地址

p指的是指针所指向的内容的地址

实参传递的是实参a,b的地址,形参a,b为指针类型的变量,也就是对应存放的是实参a,b变量的地址,函数内交换形参a,b指针所指向地址的内容,也就是交换了实参a,b地址指向空间的内容,所以实参a,b的内容被交换。

图解:

实参本身为指针

一级指针

代码:

#include<iostream>
using namespace std;void newPoint(int *p)
{cout<<"parameter p address = "<<&p<<endl;p = new int;*p = 10;
}int main()
{int *p = NULL;cout<<"argument p address = "<<&p<<endl;newPoint(p);cout<<"*p = "<<*p<<endl;delete p;return 0;
}
~           

执行结果:

分析结果:

实参指针p 没有指向任何类容为空,当实参给形参传递值时,传递的实际上是NULL,形参指针p 分配空间,仅仅只是给形参p分配了空间,当函数退出时,实参指针指向的内容还是为空,这时去访问实参p指向的内容,因为指针没有指向确切地址,就会产生段错误,同时因为函数new了空间没有释放,还会造成内存泄漏。

二级指针

代码:

#include<iostream>
using namespace std;void newPoint(int **p)
{cout<<"parameter p address = "<<&p<<endl;*p = new int;cout<<"parameter p value = "<<p<<endl;cout<<"parameter *p value = "<<*p<<endl;**p = 10;
}int main()
{int *p = NULL;cout<<"argument p address = "<<&p<<endl;newPoint(&p);cout<<"argument p value = "<<p<<endl;cout<<"*p = "<<*p<<endl;delete p;return 0;
}
~       

执行结果:

结果分析:

实参给形参传递的值是实参本身的地址 0x7ffe7feaa980,形参类型是二级指针,形参p存放的是一级指针实参p的地址,调用new之后,相当于是给实参指针p分配了空间,实参指针指向的地址为0x55d013b6d280,给**p赋值,相当于是给地址0x55d013b6d280指向的空间赋值,所以当函数返回时,实参指针指向了确定的地址0x55d013b6d280,并且地址0x55d013b6d280指向的空间值为10;

图解:

引用传值

代码:

#include<iostream>
using namespace std;void swap(int& a,int& b)
{cout<<"parameter a address = "<< &a<<endl;cout<<"parameter b address = "<< &b<<endl;a = a+b;b = a-b;a = a-b;}int main()
{int a = 10;int b = 20;cout<<"argument a address = "<<&a<<endl;cout<<"argument b address = "<<&b<<endl;cout<<"original value"<<"a = "<<a<<" b ="<<b<<endl;swap(a,b);cout<<"swap value"<<"a = "<<a<<" b ="<<b<<endl;return 0;
}
~     

运行结果:

结果分析:

引用传值,函数形参并没有给形参分配内存,而是和实参相同的内存地址,节省了开销,建议能用引用传值的就用引用。

图解:

函数传参问题(指针传参,值传参,引用传参):相关推荐

  1. 【C语言进阶】⑤关于数组传参和指针传参辨析

    文章目录 一.数组 1.1.一维数组 1.2.二维数组 1.3.指针和数组 二.数组传参 2.1一维数组传参 2.2二维数组传参 2.3小结 三.指针传参 3.1一维指针传参 3.3二级指针传参 四. ...

  2. php值传参,引用传参以及对象传参

    传值:是把实参的值赋值给行参 ,那么对行参的修改,不会影响实参的值 传引用 :真正的以地址的方式传递参数传递以后,行参和实参都是同一个对象,只是他们名字不同而已对行参的修改将影响实参的值 说明: 传值 ...

  3. 指针-数组传参,指针传参

    目录 数组传参 一维数组 二维数组 指针传参 一级指针 二级指针 一个特殊的二级指针 数组传参 一维数组 我们把传入一维数组时输入的是数组名,数组名是一个指向首元素的指针 那么在函数接收时,只需要保证 ...

  4. 【php7扩展开发四】函数的参数 ,引用传参 ,返回值

    函数参数解析 之前我们定义的函数没有接收任何参数,那么扩展定义的内部函数如何读取参数呢?用户自定义函数在编译时会为每个参数创建一个zend_arg_info结构,这个结构用来记录参数的名称.是否引用传 ...

  5. C/C++ 一维数组的传参/一级指针的传参 二维数组的传参/二级指针的传参 三维数组的传参/三级指针的传参 方法总结分析终极篇

    序 最近复习c/c++数组的传参,发现了一些问题,下面是一些总结和思考 正文 一维数组的传参/一级指针的传参/普通指针 在理解指针的基础上,一维数组的指针传递很简单,我们知道数组的数组名就是这个数组首 ...

  6. c++ 引用传参和指针传参的区别

    概念 指针从本质上讲是一个变量,变量的值是另一个变量的地址,指针在逻辑上是独立的,它可以被改变的,包括指针变量的值(所指向的地址)和指针变量的值对应的内存中的数据(所指向地址中所存放的数据). 引用从 ...

  7. Python当中的a += a 与 a = a + a 的区别,可变类型与不可变类型的数据类型,引用传参...

    a += a 与 a = a + a 的区别 可变类型a = a + a 的示例 In [58]: a = [11,22]In [59]: id(a) Out[59]: 140702917607688 ...

  8. @modelattribute注解用postman测试怎么传参_谁要是再敢用Map传参,我过去就是一JIO...

    还记得上次我写过一篇关于实际项目代码分层和规划的文章<看完这篇,别人的开源项目结构应该能看懂了>, 在文尾处提到过一些注意事项,其中第一条就是: Contorller层参数传递建议不要使用 ...

  9. vue页面传参(多个参数传值)与接参 - 代码篇

    index.js路由规则设定: /searchResult/syyName=:syyName 发送页面: //传参页面 this.$router.push({name: 'SearchResult', ...

  10. 在给函数传递实参时,不能对用到引用的传NULL

    在给函数传递实参时,不能对用到引用的传NULL FillRetBuff(buff,1024*1000,NULL,&paramElem); 在声明时为  int FillRetBuff(char ...

最新文章

  1. 5个REST API安全准则
  2. C++ Vector用法深入剖析
  3. hdu 1789 Doing Homework again
  4. 吴恩达《Machine Learning》精炼笔记 4:神经网络基础
  5. vue如何在用户要关闭当前网页时弹出提示
  6. 函数-函数的基本组成
  7. 微软 MS Learn 上线 Blazor 入门教程
  8. jquery选择器之属性选择器
  9. C++开源矩阵计算工具——Eigen的简单用法(三)
  10. signature=b21ede5d7e667b061a2058d2d4aba643,【D2D8524B18023CCDD6DBEEF2AB467
  11. BarTender怎么打印公式化的三列标签
  12. 十年工龄的程序员为你揭示最危害程序员职业生涯的三大观念
  13. 随机信号分析学习笔记(5)
  14. Tracert 工作原理
  15. haskell 基础题解(19)
  16. 【专访】黄健宏:为什么真正的聪明人喜欢用笨方法?
  17. numpy模块基础篇
  18. Robotic KDL library
  19. Windows无法安装,选中的磁盘为GPT分区形式 --解决办法
  20. 深度学习及并行化实现概述

热门文章

  1. <ctime>, clock()
  2. php设计模式-组合模式的运用
  3. 国产航顺HK32F030M:TM1624四位数码管驱动显示
  4. 企业网站的搜索引擎优化
  5. AD shift+space 解决办法
  6. 毕设-校园二手交易平台
  7. 深入理解高并发技术dpdk无锁队列
  8. 聊城大学matlab试题,聊城大学计算机学院11—12学年第2学期期末考试《编译原理》试题(闭卷B卷)...
  9. 2023年最新前端面试题(数组相关)
  10. 局部响应归一化LRN (Local Response Normalization)