c#参数值传递与引用传递的剖析
来源:互联网 发布:科比06赛季场均数据 编辑:程序博客网 时间:2024/04/29 12:41
引子:以两个人在两台机器的文件拷贝做例子,值传递好比是你把文件复制一份,通过网络传给他,然后他可以在他本机上对文件做任何的修改,修改会保存下来,但是你机器上的文件不会发生任何的变化。即形参与实参是两个不同的变量,各自占用不同的存储单元;地址传递好比是你把文件在网络上的地址告诉他人,他人通过网络访问你机器上的文件,他可以对文件进行修改并保存,此时,文件的内容就会发生变化。即形参与实参是相同的变量,占用同一段内存空间。
传值的过程:
(1)形参与实参各占一个独立的存储空间。
(2)形参的存储空间是函数被调用时才分配的。调用开始,系统为行参开辟一个临时存储区,然后将各实参之值传递给形参,这时形参就得到了实参的值。
(3)函数返回时,临时存储区也被撤销。
传值的特点:单向传递,即函数中对形参变量的操作不会影响到调用函数中的实参变量。
地址传递过程:
参数是地址,实参和形参共享一个存储单元(也可以理解将实参的地址赋值给形参),对形参的操作相应的就改变了实参,此时参数传递是双向的。
Eg: 1(值类型的变量 进行值传递和引用传递)
using System;
public class PassParameter
{
public int val;
public static void
{
PassParameter Test=new PassParameter();
Test.val=100;
Console.WriteLine("1.执行传递之前实参的值为:"+Test.val);
TestPassParameter(Test.val); // 改成 TestPassParameter(Test.val);
Console.WriteLine("2.执行传递之后实参的值为:"+Test.val);
}
public static void TestPassParameter(int tmpval)
// 上面改成public static void TestPassParameter(int tmpval)
{
tmpval=200;
}
}
值传递结果100,100(引用传递结果100,200)
利用引用类型变量进行值传递:传递是原引用变量的副本,即把原引用变量复制一份传递给方法,使得方法中的行参和实参引用的值相同,指向同一个对象的实例;引用类型变量是以对象引用的形式传递的,是将要传递的对象的引用复制给函数的形参,这时形参是实参引用的复制,注意:是引用的复制,而不是原引用,和原引用指向相同的对象,因此对于引用对象所做的更改将会直接影响原来的值,但是对于引用本身,在函数内的任何改变将不会影响原引用。
using System;
class A
{
public string data="";
}
class Program
{
static void F( A a1)
{
//a1指向传来的对象a
a1.data = "2";//修改a1指向的对象
a1 = new A();//a1指向另一个对象,注意,这时a1已经不指向原来的对象a了,而原来的引用还是指向对象a
a1.data = "3";//修改新建的对象,不会影响原来对象a的值
}
static void Main()
{
A a = new A();//实例化A的一个对象,并用a1指向该对象
a.data = "1";//将a的data字段赋值为"1"
F(a);//调用函数F,注意:这时将对象a的引用(不是对象a)赋值给参数a1,
Console.WriteLine(a.data);
}
}
结果是2 而不是3也不是1.
利用引用类型参数进行引用传递:传递的是引用变量的引用,此时形参相当于是实参的一个别名,两者是同一个引用;对于已经是引用类型的参数,大家可能会说那不是多此一举吗?其实不然,因为其中的实机理完全不一样:
考查上个示例的变种
using System;
class A
{
public string data="";
}
class Program
{
static void F( ref A a1)
{
//a1和a是同一个实例,而不是指向同一对象的引用,即a1和a在存在于内存中的地址是一样的
a1.data = "2";//修改a1指向的对象
a1 = new A();//a1指向另一个对象,理所当然别名a也指向该对象了,注意,这时原来的对象已经没有任何引用指向了,因此,可以说原来的对象已经不可访问了。
a1.data = "3";//修改新建的对象的属性
}
static void Main()
{
A a = new A();//实例化A的一个对象,并用a1指向该对象
a.data = "1";//将a的data字段赋值为"1"
F(ref a);//调用函数F,注意:这时将对象a的引用传给a1,不是赋值,相当于给a对象的引用起了个别名
Console.WriteLine(a.data);//这时a已经指向函数中新建的对象,因此值应为"3"
}
}
- c#参数值传递与引用传递的剖析
- c#引用参数传递的深入剖析
- c#引用参数传递的深入剖析
- C#参数的传递:值传递、引用传递、输出参数
- C#中方法参数的引用传递、值传递。
- 数据结构 第三讲--参数的值传递与引用传递
- C#参数传递:值传递和引用传递
- C#值传递与引用传递
- C# 值传递与引用传递的区别
- C#形参,实参,值传递参数,引用传递参数,输出参数,参数数组的学习
- 参数传递(值传递与引用传递)
- C# - 函数参数的传递(值传递和引用传递)
- 深度剖析“引用传递”与“指针传递”的区别
- 关于C#的引用参数传递
- 参数的值传递,指针传递和引用传递
- Java方法参数的传递机制,值传递?引用传递?
- Java的参数传递有值传递和引用传递
- C++ 参数指针传递、引用传递、值传递的区别
- 花钱是一种风度
- Visual C++ 2005 中的命名返回值优化
- php用Smarty模板生成html文件
- 读取xml 文件
- 30岁而立之前成功12条黄金法则
- c#参数值传递与引用传递的剖析
- C#属性的理解
- C#编程命名规则
- Hashtable用法
- 动态生成控件 并捕捉事件
- 对象与引用变量-----初学c#者的困惑
- ACE Proactor前摄器模式的服务器端代码
- 需求帮助
- 寻求帮助