引用Reference

传值和传引用

  1. 传值 vs. 传引用

    • java和python只支持传值(pass by value)
    • c++和c#两者都支持
  2. 传变量的测试

    在java/c++/c#中测试以下代码:

    java实现:

    /*
     * @Author: sanjayzhong
     * @Github: https://github.com/sanjayzzzhong
     * @Date: 2019-09-06 13:58:40
     */
    public class test_object {
        public static void main(String[] args) {
            int a = 1;
            foo(a);
            System.out.println(a);
            
        }
        public static void foo(int x){
            x += 1;
        }
    }
    

    运行输出为

    1
    

    用c++实现:

    #include <iostream>
    #include <cassert>
    using namespace std;
    
    void foo(int x){
        x += 1;
    }
    
    int main()
    {
        int a;
        a = 1;
        foo(a);
        assert(a == 2);
        return 0;
    }
    

    运行结果如下:

    a.out: test_value.cpp:14: int main(): Assertion `a == 2' failed.
    [1]    9284 abort      ./a.out
    

    也就是a的值没有改变。

    a和x都是在栈生成的:

    地址变量值变量名
    10042x
    10001a

    如果用c++的引用来使函数的值改变,则如下:

    /*
     * @Author: sanjayzhong
     * @Github: https://github.com/sanjayzzzhong
     * @Date: 2019-09-06 13:38:34
     */
    #include <iostream>
    #include <cassert>
    using namespace std;
    
    void foo(int &x){   //c++ reference
        x += 1;
    }
    
    int main()
    {
        int a;
        a = 1;
        foo(a);
        assert(a == 2);
        return 0;
    }
    

    运行没有出现任何东西,说明a已经改变为2了。

    来看一下引用的内存变化:

    地址变量值变量名
    1004#1000(存的值是地址)x
    10001a

    其实c++中的引用本质上是用指针来实现的,可以认为引用是指针的语法糖。

    语法糖(Syntactic sugar)是由英国计算机科学家彼得·蘭丁发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员使用。语法糖让程序更加简洁,有更高的可读性。

    上面代码与下面的代码完全等价(但有些区别):

    /*
     * @Author: sanjayzhong
     * @Github: https://github.com/sanjayzzzhong
     * @Date: 2019-09-06 13:38:34
     */
    #include <iostream>
    #include <cassert>
    using namespace std;
    
    void foo(int *x){  //c++ pointer
        (*x) += 1;
    }
    
    int main()
    {
        int a;
        a = 1;
        foo(&a);
        assert(a == 2);
        return 0;
    }
    

    具体区别:

    • 引用不能为NULL
    • 在foo函数中引用x不能指向其他对象

    引用不仅仅是语法糖,而且比指针的限制更多。

  3. 传对象object的测试

    java代码

    /*
     * @Author: sanjayzhong
     * @Github: https://github.com/sanjayzzzhong
     * @Date: 2019-09-06 14:05:23
     */
    public  class TestObject {
        public static void main(String[] args) {
            int a = 1;
            foo(a);
            System.out.println(a);
        }
    
        public static void foo(Integer x){
            x += 1;
        }
    }
    

    最后运行,得到的结果为

    1
    

    也就是说,传object没有改变a的值。其实上面的关键代码中,java进行了拆箱和装箱的操作:

    void foo(Integer x){
        int v = x; //拆箱
        v += 1;
        v = new Integer(v); //装箱
    }
    
  4. 怎么通过传值来修改值呢(pass-by-value)

    • 用数组的形式(array)

      # -*- coding: UTF-8 -*-
      '''
      @Author: sanjayzhong
      @Github: https://github.com/sanjayzzzhong
      @Date: 2019-09-06 14:18:41
      '''
      def foo(x):
          x[0] += 1
      
      a = [1]
      foo(a)
      assert(a[0] == 2)
      
    • 用类成员(class member)

      # 暂时没懂 留坑
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zedjay_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值