首页 > 代码库 > 引用和指针的区别

引用和指针的区别

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

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; 对应的汇编代码中可以看出对于引用类型也是分配了空间的,空间中保存的是被引用量的地址,这和指针的方式也是一致的。