值类型和引用类型,形参和实参,传值和传引用

  •     C# 中有两种类型:引用类型和值类型。引用类型的变量存储对其数据(对象)的引用地址),而类型的变量直接包含其数据(副本)。


  •     对于引用类型,两种变量可引用同一对象;因此,对一个变量执行的操作会影响另一个变量所引用的对象。对于值类型,每个变量都具有其自己的数据副本,对一个变量执行的操作不会影响另一个变量(ref 和 out 参数变量除外)。


  •     形参:函数定义时所带的参数如:void add(int i,double t)中的 i 和 t  

  •     实参:将要传人函数内进行运算的参数,可以是变量、常量,与形参类型相同;如:add( 1 , 2 )中 1 和 2 就是实参——实际参数  实参和形参区别

  • 传值:
  • 只会在调用函数的这个作用域中起作用。 

    传值调用的情况是这样的:实参把值传入堆栈然后发生传递过程,形参接受这个值,也可以改变这个值,形参可以在自身的函数中有很多变量,可以进行运算,改变他们的值,但问题的关键是,这些变量开辟的内存空间都是在堆栈中的,在调用结束的一瞬间堆栈全都释放弹栈了,所有的堆栈的内存空间都没了,存放的数据也就跟着消失了。这个就是传值不影响实参的根本原因。

        在函数调用中发生的数据传送是单向的。 即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。 因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。

    传引用:

       真正的以地址的方式传递参数

       传递以后,行参和实参都是同一个对象,只是他们名字不同而已对行参的修改将影响实参的值。

       它其实和传值基本一样的传送过程,但是关键就在于在刚开辟堆栈的时候,它放入的是由主调函数放进来的实参变量的地址,被调函数对形参的任何操作都被处理成间接寻址,即通过堆栈中存放的地址访问主调函数中的实参变量,那么形参在修改的时候,修改的就是实参地址所对应的值,也就是实参的值,虽然随着堆栈的消失,这个实参地址和形参都消失了,但修改的内容却不在堆栈所开辟的内存中,它一直存在着,而且这个内存就是原来用来存放实参的。


    何时传值、何时传引用:

    如果传递的参数是基元类型(int,float等)或结构体(struct),那么就是传值调用。
    如果传递的参数前有ref或者out关键字,那么就是传引用调用。
    如果传递的参数是类(class)并且没有ref或out关键字:
         如果调用的函数中对参数重新进行了地址分配(new操作),那么执行结果类似传值调用
         如调用的函数中没有对参数重新进行了地址分配,直接就是使用了传递的参数,执行结果类似传引用调用

     举个例子:   

         String是final类型,比如String s="123"; s = "abc",后面的“abc”其实是新建了一个string对象,并重新将其地址给了s。所以函数内的string对象是副本,副本重新指向另外一个地址,对本来的string对象无影响。
         而StringBuffer非final类型,StringBuffer s=“123”;s=“ABC”其传入函数的是他的对象地址的副本,还是指向同一对象。在函数内对其副本操作,等同于对原来StringBuffer对象的操作。

  • thanks for your time

评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值