zoukankan      html  css  js  c++  java
  • 引用和指针的区别

    引用和指针有如下三种区别:

    1 引用必须在声明时初始化,而指针不用;

    2 对于NULL不能引用,而指针可以指向NULL;

    3 引用一旦声明,引用的对象不能改变(但对象的值可以改变);而指针可以随时改变指向的对象。

    引用能做到的,指针也可以,但指针更危险;

    (1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化)。

    (2)不能有NULL引用,引用必须与合法的存储单元关联(指针则可以是NULL)。

    (3)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)。

    从上面的区别看,引用比指针安全。从编译器的角度看,引用仅仅是一个更为安全的指针。正是因为指针非常灵活,导致指针在编程时出错的可能性也很大,可以这样说指针是C++中最危险的。为了在不牺牲性能的情况下,更安全的利用指针特性,C++引入了引用。

    实例分析:

    #include <iostream>
    
    void swapint1(int *a,int *b)
    {
        int temp;
        temp=*a;
        *a=*b;
        *b=temp;
    }
    
    void swapint2(int &a,int &b)
    {
        int temp;
        temp=a;
        a=b;
        b=temp;
    }
    
    int main()
    {
        int a = 3;
        int b = 4;
        int &c = a; 
        c = 12;
        swapint1(&a,&b);
        swapint2(a,b);
        return 0;
    }
    swapint1和swapint2对应的汇编代码:
    swapint1:
        pushl    %ebp
        movl    %esp, %ebp
        subl    $16, %esp
        movl    8(%ebp), %eax
        movl    (%eax), %eax
        movl    %eax, -4(%ebp)
        movl    12(%ebp), %eax
        movl    (%eax), %edx
        movl    8(%ebp), %eax
        movl    %edx, (%eax)
        movl    12(%ebp), %eax
        movl    -4(%ebp), %edx
        movl    %edx, (%eax)
        leave
        ret
    
    swapint2:
        pushl    %ebp
        movl    %esp, %ebp
        subl    $16, %esp
        movl    8(%ebp), %eax
        movl    (%eax), %eax
        movl    %eax, -4(%ebp)
        movl    12(%ebp), %eax
        movl    (%eax), %edx
        movl    8(%ebp), %eax
        movl    %edx, (%eax)
        movl    12(%ebp), %eax
        movl    -4(%ebp), %edx
        movl    %edx, (%eax)
        leave
        ret

    从上面的代码可以看出,两种函数的实现在汇编层面是完全一样的。然后再从调用的层面进行分析。

    // int a = 3
    movl    $3, 24(%esp)
    
    // int b = 4
    movl    $4, 20(%esp)
    
    // int &c = a;
    leal    24(%esp), %eax
    movl    %eax, 28(%esp)
    
    // c = 12
    movl    28(%esp), %eax
    movl    $12, (%eax)
    
    // swapint1(a,b)
    leal    20(%esp), %eax
    movl    %eax, 4(%esp)
    leal    24(%esp), %eax
    movl    %eax, (%esp)
    call    swapint1
    
    // swapint2(a,b)
    leal    20(%esp), %eax
    movl    %eax, 4(%esp)
    leal    24(%esp), %eax
    movl    %eax, (%esp)
    call    swapint2

    可见两种实现方式在调用的角度也是一样的,均是采用传地址的方式来实现的。

    另外,从 int & c = a; c = 12; 对应的汇编代码中可以看出对于引用类型也是分配了空间的,空间中保存的是被引用量的地址,这和指针的方式也是一致的。

  • 相关阅读:
    危机边缘第五季/全集Fringe迅雷下载
    危机边缘第一季/全集Fringe迅雷下载
    混乱之子第七季/全集Sons of Anarchy迅雷下载
    混乱之子第一季/全集Sons Of Anarchy迅雷下载
    都市侠盗第五季/全集Leverage迅雷下载
    都市侠盗第一季/全集Leverage迅雷下载
    识骨寻踪第十二季/全集Bones迅雷下载
    识骨寻踪第一季/全集Bones迅雷下载
    神盾局特工第四季/全集Agents Of SHIELD迅雷下载
    福尔摩斯基本演绎法第一季/全集Elementary迅雷下载
  • 原文地址:https://www.cnblogs.com/yanenquan/p/3721850.html
Copyright © 2011-2022 走看看