MST
星途 面试题库

面试题:C++ 中指针与引用的区别

请详细阐述 C++ 中指针与引用的区别,包括但不限于定义、初始化、内存分配、可修改性、空值处理、应用场景等方面。
42.6万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

定义

  • 指针:指针是一个变量,其值为另一个变量的地址,即内存位置的直接地址。通过使用 * 运算符来声明指针类型,例如 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,因为引用必须始终绑定到一个有效的对象。试图创建一个空引用是不合法的,会导致编译错误。

应用场景

  • 指针
    • 动态内存分配:在使用 newdelete 操作符进行动态内存分配和释放时,通常使用指针来管理这些动态分配的内存。例如:
int* dynamicArray = new int[10];
// 使用完后释放内存
delete[] dynamicArray;
- **实现数据结构**:如链表、树等动态数据结构,指针用于连接各个节点。
- **函数参数传递**:当需要在函数中修改传入变量的值,或者传递一个可能为空的对象引用时,指针是一个合适的选择。
  • 引用
    • 函数参数传递:当希望避免对象的拷贝,并且确保函数内部对参数的修改反映到调用者的变量上时,引用是常用的选择。特别是对于大型对象,使用引用传递可以提高性能。例如:
void modifyValue(int& value) {
    value++;
}
int num7 = 10;
modifyValue(num7); // num7 的值变为 11
- **运算符重载**:在重载某些运算符(如 `operator<<` 用于输出流操作)时,常使用引用作为参数,以避免不必要的对象拷贝。