相似之处
间接访问对象:引用和指针都可以通过它们来间接访问和操作某个对象的值,而不是直接使用该对象的名字。
作为函数参数传递:两者都可以作为函数参数,允许函数操作调用者传递的对象,而不是对象的副本。
-
引用示例:
void modify(int& ref) {ref = 20; // 直接修改传入的参数 }
-
指针示例:
void modify(int* ptr) {*ptr = 20; // 通过解引用修改传入的参数 }
不同之处
语法上的区别
-
引用:
- 语法上类似变量的别名,一旦定义,必须绑定到一个对象,且无法重新绑定。
- 使用时不需要显式解引用,访问时与直接使用变量一样。
int x = 10; int& ref = x; // ref 是 x 的引用 ref = 20; // 相当于修改 x,x 现在是 20
-
指针:
- 是一种变量,存储的是另一个对象的地址。
- 使用时需要通过解引用运算符
*
来访问指向的对象。 - 可以指向
nullptr
或指向不同的对象,可以动态改变指向。
int x = 10; int* ptr = &x; // ptr 存储 x 的地址 *ptr = 20; // 通过解引用修改 x,x 现在是 20
是否允许重新绑定
-
引用:一旦绑定到一个对象,就不能再指向别的对象,即引用不能“重定向”。
int a = 10; int b = 20; int& ref = a; // ref 绑定到 a ref = b; // 修改 a 的值为 20,ref 仍然引用 a,而不是重新绑定到 b
-
int a = 10; int b = 20; int* ptr = &a; // ptr 指向 a ptr = &b; // ptr 现在指向 b,可以修改它指向的对象
空值(Null)状态
内存地址
-
指针:指针是一个变量,存储的是对象的内存地址,它本身占用一定的内存空间,并且可以通过取地址符
&
获取指针本身的地址。int x = 10; int* ptr = &x; std::cout << &ptr; // 输出指针变量 ptr 自己的地址
初始化要求
-
int x = 10; int& ref = x; // 引用必须初始化
-
指针:指针声明时可以不初始化,也可以在后面动态分配内存或改变指向的对象。
int* ptr; // 可以声明但不初始化 ptr = new int(10); // 动态分配内存
与数组的关系
-
指针:指针可以指向数组,并通过指针的偏移操作访问数组中的各个元素。
int arr[] = {1, 2, 3};int* ptr = arr; // ptr 指向数组首元素 std::cout << *(ptr + 1); // 访问第二个元素,输出 2
总结
特性 | 引用 | 指针 |
---|---|---|
是否需要初始化 | 必须在声明时初始化 | 可以声明后再初始化 |
是否能为空 | 不能 | 可以为空 (nullptr ) |
是否可重新绑定 | 不能,绑定后不能更改 | 可以重新指向不同的对象 |
访问方式 | 直接使用 | 需要使用* 解引用 |
是否可指向不同对象 | 否 | 是 |
内存占用 | 不占用额外内存 | 占用内存,存储对象地址 |
能否指向数组 | 不能用于遍历数组 | 可以用于数组遍历 |