C++指针是一种特殊的变量类型,它存储的是另一个变量的内存地址,通过指针可以直接访问或修改对应地址上的数据,是C++中操作内存的核心工具之一。指针的使用贯穿了很多底层开发场景,也是很多开发者入门时的难点。

C++指针的基础概念
指针的本质是一个存储内存地址的变量,定义指针时需要指定它指向的变量类型,语法格式为类型* 指针变量名。我们可以通过取地址符&获取变量的地址赋值给指针,也可以通过解引用符*访问指针指向的变量内容。
下面是一个简单的指针使用示例:
#include <iostream>
using namespace std;
int main() {
int num = 10; // 定义一个整型变量num
int* p = # // 定义整型指针p,存储num的地址
cout << "num的值: " << num << endl;
cout << "num的地址: " << &num << endl;
cout << "指针p存储的地址: " << p << endl;
cout << "通过指针p访问的值: " << *p << endl;
*p = 20; // 通过指针修改num的值
cout << "修改后num的值: " << num << endl;
return 0;
}
C++引用的基础概念
引用是某个已存在变量的别名,定义引用时需要用&符号,语法格式为类型& 引用名 = 原变量名。引用和原变量指向同一块内存空间,对引用的操作本质上就是对原变量的操作,引用在定义时必须初始化,且之后不能再绑定其他变量。
引用的基础使用示例如下:
#include <iostream>
using namespace std;
int main() {
int num = 10;
int& ref = num; // 定义引用ref,是num的别名
cout << "num的值: " << num << endl;
cout << "引用ref的值: " << ref << endl;
ref = 30; // 修改引用的值,等价于修改num的值
cout << "修改后num的值: " << num << endl;
cout << "修改后引用ref的值: " << ref << endl;
return 0;
}
指针和引用的核心区别
虽然指针和引用都可以间接访问变量,但两者在很多特性上存在明显差异,具体对比如下:
| 对比维度 | C++指针 | C++引用 |
|---|---|---|
| 定义要求 | 可以不初始化,初始化后可以指向nullptr | 必须初始化,且不能绑定空值 |
| 内存占用 | 本身占用内存空间,大小等于系统地址总线宽度 | 本身不占用额外内存空间,和原变量共享地址 |
| 可修改性 | 可以重新赋值,指向其他同类型变量 | 一旦初始化,不能再绑定其他变量 |
| 解引用操作 | 需要通过*解引用才能访问指向的变量 | 直接使用引用名即可访问原变量,无需解引用 |
| 多级定义 | 支持多级指针,比如int**表示指向整型指针的指针 | 不支持多级引用,没有int&&&这种语法 |
| 作为函数参数 | 传递的是地址的拷贝,修改指针本身不影响实参 | 传递的是原变量的别名,修改引用会影响实参 |
使用场景建议
在实际开发中,我们可以根据需求选择使用指针还是引用:
- 如果需要表示空值、或者需要动态改变指向的对象,优先选择指针
- 如果只需要给变量起一个别名,且不需要改变绑定关系,优先选择引用,引用使用起来更安全也更简洁
- 函数参数传递时,如果不需要修改参数本身,只是读取内容,可以用const引用,避免不必要的拷贝
需要注意的是,引用本质上在很多编译器实现中也是通过指针来实现的,但从语法层面来说,引用和指针是完全不同的两个概念,不能混为一谈。