【C++】指针&引用

pointers 指针

raw pointers

内存是计算机最重要的,内存是线性的

指针

在内存中存放地址的整数,不保存数据

在这里插入图片描述

指针需要类型的原因:需要知道内存,如果选用void类型,则会出错

c++11:可以设置空指针为 nullptr

#include <iostream>
#define Log(x) std::cout<< x << std::endl;
int main() {
    void* ptr = nullptr; //类型不能决定指针,指针只是一个地址;0意味着无效
    int var = 8;
    int* ptr2 = &var; //拿到变量地址,16进制
    *ptr2 = 10; //解引用该指针,访问该data,也可以进行读取或者写入
     Log(var);
    std::cin.get();
} //最后输出为10

memset

#include <iostream>
#define Log(x) std::cout<< x << std::endl;

int main() {
    char* buffer = new char[8]; //为我们分配了8字节内存,并返回一个指向这块内存的开始地址的指针
    memset(buffer, 0, 8);//用指定数据填充一块内存,接受一个指针指向这块内存的开始,8表示填充多少的字节
    std::cin.get();
}

在这里插入图片描述

指针的指针

int main() {
    char* buffer = new char[8]; //为我们分配了8字节内存,并返回一个指向这块内存的开始地址的指针
    memset(buffer, 0, 8);//用指定数据填充一块内存,接受一个指针指向这块内存的开始,8表示填充多少的字节
    char** ptr = &buffer;
    delete[] buffer;
    std::cin.get();
}

我们输入ptr的地址,将 b0 c4 57 4b b2 01 00 00 逆序,变成000001b24b57c4b0,则会跳转到存储buffer的地址

在这里插入图片描述

smart pointers

reference 引用

并不是变量,只是一个别名

格式

int& ref = a; 

string *ps; //未初始化的指针,有效,但风险高
int main() {
    int a = 5;
    int& ref = a; //ref不是一个变量,只是一个别称;这个ref变量并不真正存在,他只存在我们的源码里
    ref = 2;
    std::cout << a << std::endl;
    std::cin.get();
}//输出为2

实例

下面的输出为5,a并没有增加

void increment(int value) {
    value++;
}
int main() {
    int a = 5;
    increment(a);
    std::cout << a << std::endl;
    std::cin.get();
} 

正确的做法

传递这个a地址进去

void increment(int* value) {
    (*value)++;
}
int main() {
    int a = 5;
    increment(&a);
    std::cout << a << std::endl;
    std::cin.get();
}
引用传递
void increment(int& value) {
    value++;
}
int main() {
    int a = 5;
    increment(a);
    std::cout << a << std::endl;
    std::cin.get();
}

错误示范

必须立即将一个实际变量赋给他

//实例1:未立即赋值
int& ref;
ref=b;

//实例2:编译器可能产生任何可能的输出,行为有害!
char *pc=nullptr;
char& rc=*pc;

一旦申明,则不能更改对象

int main() {
    int a = 5;
    int b = 8;
    int& ref = a;
    ref = b; //ref仍然指向a,但是值变成b的值
    std::cout << a << std::endl;
    std::cin.get();
} //最终输出 a=8

差异

  1. 没有所谓的null reference,这也意味着使用reference可能会比使用指针更富效率,因为不需要测试有效性,使用pointer则需要检测其是否为null

    void printdouble(const double *pd){
    if(pd){ //检查是否为null
    cout << *pd;
    }
    }
    
  2. 指针可以被重新赋值,reference却总是指向最初获得的对象

总结

你需要考虑“不指向任何对象”的可能性时,或是考虑“在不同时间指向不同对象”的能力时,你就应该采用 pointer。前一种情况你可以将 pointer设为 null,后一种情况你可以改变 pointer 所指对象。

而当你确定“总是会代表某个对象”,而且“一旦代表了该对象就不能够再改变”,那么你应该选用 reference。还有其他情况也需要使用 reference,例如当你实现某些操作符的时候。最常见的例子就是 operator[]。这个操作符很特别地必须返回某种“能够被当做assignment 赋值对象”的东西

当需要指向某个东西,而且绝不会改变指向其他东西,或是当你实现一个操作符而其语法需求无法由 pointers 达成,你就应该选择 references。任何其他时候,请采用 pointers
要使用 reference,例如当你实现某些操作符的时候。最常见的例子就是 operator[]。这个操作符很特别地必须返回某种“能够被当做assignment 赋值对象”的东西

当需要指向某个东西,而且绝不会改变指向其他东西,或是当你实现一个操作符而其语法需求无法由 pointers 达成,你就应该选择 references。任何其他时候,请采用 pointers

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值