从赋值操作理解不同类型的函数传参
来源:互联网 发布:中国人均gdp 知乎 编辑:程序博客网 时间:2024/06/09 18:25
从赋值操作理解不同类型的函数传参
我们都知道所谓的程序,就是对传入的数据进行操作,最终将处理的数据输出给用户。那么在我们的编程中的体现,就是通过函数(或者方法)参数传入数据,然后通过函数返回值输出处理后的数据。数据的传入涉及到函数的实参和形参的传递,数据的输出涉及到函数的返回值和返回值类型的参数。函数返回值没有什么特别之处,而其他的都是函数传参的问题,既然是传参,那么传参到底传过去了什么?
函数传参与赋值操作
我们都知道函数传参涉及到形参和实参,那么实参和形参就是两个不同的变量,所以函数传参的过程,类似(或者说就是)使用实参给形参赋值的过程。那么我们先来分析按值传参的情况
图1是值类型变量的赋值操作图,我们大家都知道值类型变量直接保存变量的内容,所以赋值的过程就是将ValA保存的内容直接拷贝到ValB中,此时两个变量除了保存的值相同外,没有其他的任何关系,所以此时修改ValB的内容并不会引起ValA的变化。这是与值类型按值传参的效果是一样的。
图 1.值类型变量赋值
图2展示的是引用类型变量的赋值操作,我们都知道引用类型的变量保存的是一个地址,这个地址指向了变量内容所在的地址,也就是说引用变量保存的是一个地址。那么引用类型的赋值操作同样也是拷贝变量保存的内容,这样ValA和ValB就都指向了同样地址。如果我们修改ValB的成员,那么ValA中也会随之产生变化。我们可以看到值类型和引用类型的赋值操作是一样的,都是对变量直接保存的内容的拷贝过程。但是如果我们使用其他对象对ValB重新赋值,这时ValB就指向了其他对象,ValA还指向原来的对象并没有变化。
图 2.引用类型变量赋值
我们知道C#中引入了ref关键字,使我们可以通过函数参数返回函数的处理结果,对于我们需要同时返回多项结果的时候比较有用。其实这也就是我们通常所说的按引用传参。图3展示了变量地址赋值操作,此时我们使用新的对象对ValB所指定的对象赋值,这是ValA也就指向了新的对象了。C#中的ref是否也是这样操作的呢?我们看以看一下下边的代码和相应的IL就知道了。
图 3.变量地址赋值操作
C#代码
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace FunctionParameter{ class PassByValue { public void PassValueParameterByReference(ref ReferencePara parameter) { parameter.a = 1; parameter = new ReferencePara(); } public class ReferencePara { public int a; public int b; } }}
对应的MSIL代码
//传递的是变量的地址.method public hidebysig instance void PassValueParameterByReference(class FunctionParameter.PassByValue/ReferencePara& parameter) cil managed{ // 代码大小 17 (0x11) .maxstack 8 IL_0000: nop //加载参数 IL_0001: ldarg.1 //加载对象的引用 IL_0002: ldind.ref IL_0003: ldc.i4.1 IL_0004: stfld int32 FunctionParameter.PassByValue/ReferencePara::a IL_0009: ldarg.1 IL_000a: newobj instance void FunctionParameter.PassByValue/ReferencePara::.ctor() //绑定对象的引用 IL_000f: stind.ref IL_0010: ret} // end of method PassByValue::PassValueParameterByReference
总结
从我们大学一开始接触计算机编程开始,我们就开始记忆两种函数传参的异同,其实传参的过程就是实参对形参赋值的过程,只不过有时拷贝的是变量的内容,有时拷贝的是变量的地址罢了。
- 从赋值操作理解不同类型的函数传参
- 不同类型变量赋值的讨论
- 从百度空间(WEB-IDEA)转载:复制构造函数和赋值操作符的区别
- 彻底理解python中函数内赋值操作和对象的可变性
- 类的赋值操作符函数
- 对openvSwitch中不同类型端口的理解
- 深入浅出SharePoint—对不同类型的字段进行赋值
- C++不同类型数值变量之间相互赋值的规则
- C语言中不同类型数据之间的赋值
- 对于拷贝构造函数和赋值构造函数的理解
- 对于拷贝构造函数和赋值构造函数的理解
- 对于拷贝构造函数和赋值构造函数的理解
- 对于拷贝构造函数和赋值构造函数的理解
- 对于拷贝构造函数和赋值构造函数的理解
- 对于拷贝构造函数和赋值构造函数的理解
- 对于拷贝构造函数和赋值构造函数的理解
- 对于拷贝构造函数和赋值构造函数的理解
- 对于拷贝构造函数和赋值构造函数的理解
- 软件架构的相关概念和实践
- DM8168 EMAC/MDIO模块(3)
- 正则表达式基础知识
- Freemarker简单实例
- 年月日正则
- 从赋值操作理解不同类型的函数传参
- QT::QKeyEvent
- Java ME引路蜂地图开发示例:本地查询
- win7 iis7 局域网内其它用户无法访问的解决方法
- CS0016: 未能写入输出文件...\App_Web_default.aspx.cdcab7d2.zii776dc.dll”--"拒绝访问。 " 解决方法
- 在Win7下Visual Studio如何使用IIS进行调试
- 光阴荏苒
- 一个JavaEE转投rails的心声
- Delegate 与 Event 的一些问题