C++ 中 & 与 * 符号用法详解:指针与引用的区别
C++ 中的 & 与 * 符号是理解内存模型的关键,& 代表引用(变量别名)或取地址操作,* 代表指针变量声明或解引用操作。掌握二者在定义与使用阶段的语义差异,能有效避免指针悬空与绑定错误。
1. 基本概念与核心区别
要深入理解这两个符号,首先需要明确指针与引用的本质差异:
- 指针(Pointer):是一个存储内存地址的独立变量。它具有独立性,既可以改变其指向的地址,也可以改变该地址中存储的数据内容。
- 引用(Reference):是现有变量的一个别名。它在逻辑上依附于原变量,因此必须在声明时立即初始化,且在整个生命周期内不能重新绑定到其他对象。
以下代码演示了二者在创建、初始化及后续修改时的行为差异:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int a = 5, b = 10, c = 15;
int *p1; // 指针可以不初始化,但指向未定义
int &d = b;// 引用必须初始化,d 成为 b 的别名
p1 = &a; // p1 指向 a 的地址
cout << "a:" << a << endl << "a的地址:" << &a << endl ;
cout << "b:" << b << endl << "b的地址:" << &b << endl;
cout << "c:" << c << endl << "c的地址:" << &c << endl;
cout << "p1(地址):" << p1 << endl << "p1所指对象:" << *p1 << endl;
cout << "d:" << d << endl << "d的地址:" << &d << endl;
d = c; // 等价于 b = c,改变的是 b 的值,非绑定关系
p1 = &c; // p1 转而指向 c 的地址
cout << endl << "修改后:" << endl << endl;
cout << "a:" << a << endl << "a的地址:" << &a << endl;
cout << "b:" << b << endl << "b的地址:" << &b << endl;
cout << "c:" << c << endl << "c的地址:" << &c << endl;
cout << "p1:" << p1 << endl << "p1所指对象:" << *p1 << endl;
cout << "d:" << d << endl << "d的地址:" << &d << endl;
return 0;
}
从执行结果可以看出:
当执行 d = c; 时,d 的地址并未改变,且始终与 b 相同。这说明引用不能重新绑定是指它一旦绑定,就不能再指向其他变量;但允许对绑定对象进行重新赋值。而指针 p1 则可以在不同变量间切换指向。
2. 定义时等号左右的不同含义
在 C++ 中,* 和 & 在声明语句右侧作为操作符使用时,含义往往容易混淆。关键在于区分“左侧的类型声明”与“右侧的操作行为”。
第1步:区分复合类型声明与取值操作
观察以下代码:
int i = 4;
int *p = &i;
在此语句中:
- 左侧的 * 与 int 结合构成复合类型 int *,表示 p 是一个指向整数的指针。
- 右侧的 & 则是“取地址符”,表示获取 i 的内存地址并赋给 p。
第2步:普通赋值中的二次操作
在非定义语句中,这两个符号同样承担不同的角色:
int a = 5, b = 10;
int *p;
p = &a; // & 在这里是取地址,让 p 指向 a
*p = 2; // * 在这里是解引用,将 a(即 p 所指对象)的值改为 2
3. 复杂声明的阅读技巧
C++ 语言规定:只有指针的引用,没有指向引用的指针。这是因为引用本身不是一个独立的对象,无法拥有它的指针。面对复杂的指针引用混合声明,可遵循“从右向左读”的原则:
- 原则:越靠近变量名的符号,越说明其本质属性。
- 示例分析:
int *&r = p;
- 首先看变量名
r。 - 紧邻右侧是 &,说明
r本身是一个引用。 - 再往左看是 *,说明这个引用所绑定的对象是一个指针。
- 结论:
r是对一个指针变量的引用。
以上就是 C++ 中 & 与 * 符号用法的详细内容,更多关于 C++ 指针与引用的基础资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









