• C++_01_引用与指针


    区别与联系

    相同点:

    • 指针指向一块内存,它的内容是所指内存的地址;引用是某块内存的别名。

    区别:

    1. 指针是一个实体,而引用仅是个别名;
    2. 引用使用时无需解引用(*),指针需要解引用;
    3. 引用只能在定义时被初始化一次,之后不可变;指针可变;引用“从一而终” _
    4. 引用没有 const,指针有 const,const 的指针不可变;
    5. 引用不能为空,指针可以为空;
    6. “sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身(所指向的变量或对象的地址)的大小;typeid(T) == typeid(T&) 恒为真,sizeof(T) == sizeof(T&) 恒为真,但是当引用作为成员时,其占用空间与指针相同(没找到标准的规定)。
    7. 指针和引用的自增(++)运算意义不一样;

    引用的主要功能

    引用的主要功能是传递函数的参数和返回值。

    C++语言中,函数的参数和返回值的传递方式有三种:值传递、指针传递和引用传递。

    值传递:

    void func1(int x)
    {
        x += 10;
    }
    // ...
    int a = 0;
    func1(a);
    cout << "a = " << a << endl; // a = 0
    

    由于func1函数体内的x是外部变量n 的一份拷贝,改变x 的值不会影响a, 所以a 的值仍然是0.

    指针传递:

    void func2(int * x)
    {
        * x = (* x) + 10;
    }
    ⋯  
    int b = 0;
    func2(&b);
    cout << "b = " << b << endl; // b = 10
    

    由于func2 函数体内的x 是指向外部变量b 的指针,改变该指针的内容将导致b 的值改变,所以b 的值成为10.

    引用传递:

    void func3(int & x)
    {
        x += 10;
    }
    //...  
    int c = 0;
    func3(c);
    cout << "c = " << c << endl; // c = 10
    

    由于func3 函数体内的x 是外部变量n 的引用,x和c 是同一个东西,改变x 等于改变c,所以c 的值成为10.

    对比上述三个示例程序,会发现“引用传递”的性质象“指针传递”,而书写方式象“值传递”。实际上“引用”可以做的任何事情“指针”也都能够做,为什么还要“引用”? 指针能够毫无约束地操作内存中的如何东西,尽管指针功能强大,但是非常危险。

    指针可以为空,引用不能为空。

    这就意味着我们拿到一个引用的时候,是不需要判断引用是否为空的,而拿到一个指针的时候,我们则需要判断它是否为空。这点经常在判断函数参数是否有效的时候使用。

    void fun1(int *point)
    {
         // 为了代码的稳健和安全,我们需要判断指针是否有效,通常做法是判断指针是否为
         // 空,其他的判断就需要根据函数的具体功能来判断了
         if(!point)
         {
            return;
         }
         // 函数实现
    }
    
    void fun2(int &refence)
    {
         // 在这里,我们就不用担心refence是否为空
    }
    
    // 作者:nkaifang
    // 链接:https://www.zhihu.com/question/37608201/answer/90293843
    // 来源:知乎
    // 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    

    引用修饰函数参数还可以提高效率,例子如下:

    Class Object
    {// 实现省略,只需要知道我们在这里声明了一个类,在下面我们要将这个类的对象作为
     // 函数参数类型来使用};
    void fun1(Object obj)
    {
         // 此函数声明中,obj是值传递,会产生一个临时对象
    }
    void fun2(Object &obj)
    {
        // 我们不用检查obj是否为空,同时,使用引用传递,可以避免临时对象
    }
    

    指针可以多次赋值,即在某时刻可以指向地址1,换个时候可以指向地址2,例如:

    int a = 0;
    int b = 1;
    int *point = NULL;
    point = &a;     // 在某个时刻,指针可以指向a
    point = &b;     // 换个时刻,指针可以指向b
    

    而引用则不同,引用只能在初始化的时候就指定了所引用的变量,对象等等,之后就不能改变了,用外号的例子来说就是"明明"这个外号在出现的时候就是代指小明,之后“明明”这个外号就绑在小明身上了,它不会过段时间换成小暗的外号。代码如下:

    int xiaoming = 1;
    int &refence_mingming = xiaoming;
    int xiaoan = 2;
    &refence_mingming = xiaoan;           // error,一个引用在初始化后就固定下来,不能再变化.
    

    由以上可以,当我们需要某个是否指向为空的时候,我们就需要使用指针了,还有指向的对象需要变化的时候,我们也需要使用指针。其他地方一般推荐引用。

    引用的本质

    引用实际上就是基于指针加了一些语法糖,比如必须初始化、不能改变引用的指向等等。

    但是引用是别名这是c++语法规定的语义,那么到底引用在汇编层面和指针有什么区别呢? 没区别。 对,引用会被c++编译器当做const指针来进行操作。

    TODO


    Reference:

  • 相关阅读:
    网页端打开手机上的app
    iOS 9学习系列:打通 iOS 9 的通用链接(Universal Links)
    自定义 URL Scheme 完全指南
    App开发流程之加密工具类
    iOS8系统H264视频硬件编解码说明
    人脸识别
    app上线具体流程
    第三方分享
    Android摸索-二、解决Android SDK Manager下载太慢问题
    Android摸索一环境搭建
  • 原文地址:https://www.cnblogs.com/cloudflow/p/16366429.html
Copyright © 2020-2023  润新知