c++ 指针与引用区别

1.基本概念

指针:指的是一块内存的地址值。
引用:是一块内存的别名。

指针本质上就是存放变量地址的一个变量,逻辑上是独立的。他可以被改变,包括其指向的地址的改变和其指向的地址中所存放的数据的改变。

而引用只是一个别名,逻辑上并不存在,在整个引用周期是不能被改变的,只能指向同一个变量。

2.能否为空值

指针是可以为空值的,可以不需要初始化。平时编程中,最讨厌的情况就是看到各种NullPointer,排查起来都不好排查。
引用不能为空值,因此必须进行初始化。所以引用的一个优点是它一定不为空,相对于指针不用检查它所指对象是否为空,这样增加了效率。

3.通过实例测试

#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;

int main(int argc, char const *argv[])
{
    int a = 1, b = 2, c = 3;
    int *p1;
    int &d = b;
    p1 = &a;

    printf("a: %d, a address is: %p\n", a, &a);
    printf("b: %d, b address is: %p\n", b, &b);
    printf("c: %d, c address is: %p\n", c, &c);
    printf("p1的地址为: %p, p1的数据为: %d\n", p1, *p1);
    printf("d: %d, d address is: %p\n\n", d, &d);

    d = c; // 等于b=d=c;
    p1 = &c; // 指针的地址可以变

    printf("a: %d, after modify, a address is: %p\n", a, &a);
    printf("b: %d, after modify, b address is: %p\n", b, &b);
    printf("c: %d, after modify, c address is: %p\n", c, &c);
    printf("p1的地址为: %p, p1的数据为: %d\n", p1, *p1);
    printf("d: %d, after modify, d address is: %p\n", d, &d);

    return 0;
}

代码输出为:

a: 1, a address is: 0x7ffee6a3333c
b: 2, b address is: 0x7ffee6a33338
c: 3, c address is: 0x7ffee6a33334
p1的地址为: 0x7ffee6a3333c, p1的数据为: 1
d: 2, d address is: 0x7ffee6a33338

a: 1, after modify, a address is: 0x7ffee6a3333c
b: 3, after modify, b address is: 0x7ffee6a33338
c: 3, after modify, c address is: 0x7ffee6a33334
p1的地址为: 0x7ffee6a33334, p1的数据为: 3
d: 3, after modify, d address is: 0x7ffee6a33338

从上面代码不难看出,p1是可以改变其指向的内存地址的。而d不能改变指向的内存地址,只能改变该内存地址的存储数据。

4.引用的使用场景

引用的主要功能就是作为函数的参数和返回值。

看以下的例子,以常见的交换两个数字值为例。

#include<iostream>
#include<cstdlib>
using namespace std;

void swap(int a, int b) {
    int tmp;
    tmp = a;
    a = b;
    b = tmp;
}

void swap2(int* a, int* b) {
    int tmp;
    tmp = *a;
    *a = *b;
    *b = tmp;
}

void swap3(int &a, int &b) {
    int tmp;
    tmp = a;
    a = b;
    b = tmp;
}

int main(int argc, char const *argv[])
{
    int i = 1, j = 2;
    //swap(i, j);
    //swap2(&i, &j);
    swap3(i, j);
    printf("i=%d, j=%d", i, j);
    return 0;
}

上面有三种传递参数的方式:直接传递变量名,传递变量地址,以及传递引用。

如果我们执行swap(i, j)方法,显然在函数调用结束以后,main方法里面的i,j值并没有发生变化。

执行swap2(&i, &j)方法,形参是指针变量,实参是一个变量的地址,调用函数时,形参得到的实参变量的地址,因此指向实参的变量单元,可以实现在main方法里交换i,j值的目的。但是该方法不够直观,而且依旧是“值传递”的方式,只不过传递的是变量的地址而已。

当执行swap3(i, j)方法时,形参是声明的引用,调用函数的过程中,实现了引用的初始化,这是传入的实参就是变量,而不是数值,所以做到了真正意义上的“变量传递”,最后在main方法里面也交换了i, j的数值。

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值