C++中的指针和引用都是用于间接访问内存的工具,但它们在语法和语义上有一些重要的区别。
1. 定义和初始化:
- 指针:指针是一个变量,用于存储内存地址。它需要通过使用星号(*)来声明,并使用取地址运算符(&)初始化,可以在声明时或稍后进行初始化。
int* ptr; // 声明一个整型指针
int* ptr = # // 初始化指针,指向变量num的地址
- 引用:引用是一个别名,用于给已存在的变量起别名。它通过使用引用符号(&)声明,并在声明时进行初始化,一旦初始化完成,它将一直引用同一个对象。
int num = 10;
int& ref = num; // 声明一个整型引用,并初始化为变量num
2. 空值(nullptr 和 NULL):
- 指针:指针可以具有空值,即指向无效地址或空地址。C++11引入了`nullptr`关键字,用于表示空指针。
int* ptr = nullptr; // 使用nullptr初始化指针
- 引用:引用不可以有空值,它必须在声明时初始化,并且始终引用一个有效的对象。
3. 内存地址和操作:
- 指针:指针存储着内存地址,可以通过解引用运算符(*)访问所指向的对象,也可以通过指针运算(如加法和减法)来操作内存地址。
int num = 10;
int* ptr = # // 指针指向变量num的地址
*ptr = 20; // 解引用指针,修改变量num的值
- 引用:引用是被引用对象的别名,通过引用操作符(即引用本身)直接访问所引用的对象,无需解引用运算符。
int num = 10;
int& ref = num; // 引用变量num
ref = 20; // 直接修改变量num的值
4. 重新赋值:
- 指针:指针可以被重新赋值,允许指向不同的内存地址。
int num1 = 10;
int num2 = 20;
int* ptr = &num1; // 指针指向num1
ptr = &num2; // 重新赋值,指针指向num2
- 引用:引用在初始化后不可更改,一旦引用指向了一个对象,就无法再引用其他对象。
int num1 = 10;
int num2 = 20;
int& ref = num1; // 引用变量num1
ref = num2; // 修改num1的值,不改变引用的对象
5. 空间占用和语义:
- 指针:指针本身需要占用内存空间来存储地址,因此需要额外的内存开销。指针可以指向空值,也可以指向动态分配的内存。指针可以进行指针运算,提供更大的灵活性。
- 引用:引用不需要额外的内存空间,它只是变量的别名。引用始终引用同一个对象,无法更改引用的目标。引用更加直观和简洁,常用于函数参数传递和函数返回值。