C++ 指针与引用

目录

指针和引用的区别是什么?

1. 定义和语法

2. 内存地址

3. 空指针/空引用

4. 重新绑定

5. 运算符

6. 数组与动态内存

7. sizeof

何时使用指针,何时使用引用?

1. 使用引用的场景

2. 使用指针的场景

总结


指针和引用的区别是什么?

1. 定义和语法
  • 指针:指针是一个变量,存储另一个变量的地址,可以指向任意内存位置。
int a = 10;
int* ptr = &a; // ptr 是指向 a 的指针
  • 引用:引用是某个变量的别名,在定义后必须初始化,且一旦绑定到某个对象,就不能改变。
int a = 10;
int& ref = a; // ref 是 a 的引用
2. 内存地址
  • 指针:指针是一个变量,它存储一个内存地址,使用时可以修改指向的对象。
int a = 10;
int* ptr = &a;
ptr = nullptr; // 可以指向 nullptr 或其他对象
  • 引用:引用本质上是某个对象的别名,它直接绑定到对象,不能修改引用所指向的对象。
int a = 10;
int& ref = a;
// ref 不能重新绑定到其他对象
3. 空指针/空引用
  • 指针:指针可以为空,即可以指向 nullptr(C++11 引入)或 NULL
int* ptr = nullptr; // 指针可以为空
  • 引用:引用不能为空,必须绑定到一个有效的对象。没有“空引用”的概念,必须确保引用始终有效。
4. 重新绑定
  • 指针:指针可以在程序运行期间改变指向的对象。
int a = 10, b = 20;
int* ptr = &a;
ptr = &b; // 可以重新指向 b
  • 引用:引用在初始化后不能更改绑定的对象。
int a = 10, b = 20;
int& ref = a;
// ref = &b; // 错误,引用不能重新绑定
5. 运算符
  • 指针:指针有专门的运算符 *(解引用) 和 &(取地址)。你需要通过 * 来访问指针指向的值。
int a = 10;
int* ptr = &a;
*ptr = 20; // 修改 a 的值为 20
  • 引用:引用本质上是变量的别名,不需要使用运算符就可以直接访问对象。
int a = 10;
int& ref = a;
ref = 20; // 修改 a 的值为 20
6. 数组与动态内存
  • 指针:指针可以指向动态分配的内存,也可以遍历数组或指向对象数组的某个元素。
int* arr = new int[5]; // 指针可以指向动态分配的内存
arr[0] = 1;
delete[] arr; // 手动释放动态分配的内存
  • 引用:引用不能用于指向动态分配的内存或遍历数组。引用通常只适用于栈上的对象。
7. sizeof
  • 指针sizeof 指针返回的是指针自身的大小(一般是 4 或 8 个字节,取决于系统架构),而不是指针指向的对象的大小。
int* ptr;
std::cout << sizeof(ptr); // 输出指针的大小
  • 引用:引用本质上是对象的别名,sizeof 引用返回的是引用所指对象的大小。
int a = 10;
int& ref = a;
std::cout << sizeof(ref); // 输出 a 的大小

何时使用指针,何时使用引用?

1. 使用引用的场景
  • 简单的别名:当你不需要更改对象的引用关系,仅仅是为了给某个对象一个别名时,使用引用。
int a = 10;
int& ref = a; // ref 是 a 的别名
  • 参数传递:当函数需要修改参数值或避免不必要的拷贝时,使用引用传递参数。
void modify(int& x) {
    x = 20;
}
int a = 10;
modify(a); // a 被修改为 20
  • 常量引用:当你需要传递一个大对象但不希望修改它时,使用常量引用来避免拷贝。
void print(const std::string& str) {
    std::cout << str;
}
2. 使用指针的场景
  • 动态内存管理:当你需要在堆上分配和管理内存时,使用指针。
int* ptr = new int(10);
delete ptr; // 需要手动释放内存
  • 可能为空的对象:如果对象可能为空或者不存在时,使用指针可以表示“无对象”状态(通过 nullptrNULL)。
int* ptr = nullptr; // 指针可以为空
  • 指向不同对象:如果你需要让变量在程序运行中指向不同的对象或资源时,使用指针。
int a = 10, b = 20;
int* ptr = &a;
ptr = &b; // 可以让指针指向不同对象
  • 数组或集合遍历:指针经常用于遍历数组或集合,尤其是在低级别操作或与 C 接口交互时。
int arr[5] = {1, 2, 3, 4, 5};
int* ptr = arr;
for (int i = 0; i < 5; ++i) {
    std::cout << *(ptr + i);
}

总结

  • 引用:适用于不需要改变引用对象、参数传递、常量传递等场景,简洁、安全且高效。
  • 指针:适用于动态内存管理、可以为空的对象、多态(如通过基类指针操作子类对象)、指向不同对象或数组遍历等场景。指针灵活但需要小心内存管理和空指针问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值