面试题答案
一键面试定义
- 指针:指针是一个变量,其值为另一个变量的地址,即内存位置的直接地址。通过使用
*
运算符来声明指针类型,例如int* p;
声明了一个指向int
类型变量的指针p
。 - 引用:引用是已存在变量的别名,通过使用
&
运算符来声明引用类型,例如int a = 10; int& ref = a;
声明了一个int
类型变量a
的引用ref
。
初始化
- 指针:指针可以先声明后初始化,也可以在声明时初始化。例如:
int* p;
int num = 10;
p = #
// 或者在声明时初始化
int num2 = 20;
int* p2 = &num2;
指针在未初始化时,其值是未定义的,使用未初始化的指针会导致未定义行为。
- 引用:引用在声明时必须初始化,一旦初始化后就不能再引用其他变量。例如:
int num3 = 30;
int& ref3 = num3;
内存分配
- 指针:指针本身需要占用内存空间,用于存储所指向变量的地址。在 32 位系统上,指针通常占用 4 个字节;在 64 位系统上,指针通常占用 8 个字节。指针所指向的变量也有其独立的内存空间。
- 引用:引用本身不占用额外的内存空间,它只是目标变量的别名,与目标变量共享同一内存地址。
可修改性
- 指针:指针的值(即所指向的地址)可以在其生命周期内修改,使其指向不同的变量。例如:
int num4 = 40;
int num5 = 50;
int* p4 = &num4;
p4 = &num5;
- 引用:引用一旦初始化,就不能再引用其他变量,始终指向初始化时的那个变量。不过可以修改引用所指向变量的值。例如:
int num6 = 60;
int& ref6 = num6;
ref6 = 70; // 修改 num6 的值
空值处理
- 指针:指针可以赋值为
nullptr
(C++11 之后)或NULL
(C++11 之前),表示不指向任何有效的内存地址。在使用指针之前,通常需要检查其是否为nullptr
,以避免空指针解引用导致的程序崩溃。例如:
int* p5 = nullptr;
if (p5 != nullptr) {
*p5 = 80;
}
- 引用:引用不能为
nullptr
,因为引用必须始终绑定到一个有效的对象。试图创建一个空引用是不合法的,会导致编译错误。
应用场景
- 指针:
- 动态内存分配:在使用
new
和delete
操作符进行动态内存分配和释放时,通常使用指针来管理这些动态分配的内存。例如:
- 动态内存分配:在使用
int* dynamicArray = new int[10];
// 使用完后释放内存
delete[] dynamicArray;
- **实现数据结构**:如链表、树等动态数据结构,指针用于连接各个节点。
- **函数参数传递**:当需要在函数中修改传入变量的值,或者传递一个可能为空的对象引用时,指针是一个合适的选择。
- 引用:
- 函数参数传递:当希望避免对象的拷贝,并且确保函数内部对参数的修改反映到调用者的变量上时,引用是常用的选择。特别是对于大型对象,使用引用传递可以提高性能。例如:
void modifyValue(int& value) {
value++;
}
int num7 = 10;
modifyValue(num7); // num7 的值变为 11
- **运算符重载**:在重载某些运算符(如 `operator<<` 用于输出流操作)时,常使用引用作为参数,以避免不必要的对象拷贝。