【C++】面试:指针与引用

C++ 面试基础高频重灾区,笔试、代码题、口头追问全覆盖,话术标准、踩分点明确,可直接背诵答题。


1. 指针和引用的区别

  1. 本质不同:指针是独立变量,存放内存地址;引用是变量别名,底层依托指针实现,无独立语义。
  2. 初始化规则 :指针可延迟初始化、可置空;引用定义时必须初始化,不存在空引用。
  3. 指向修改 :指针可随时更改指向不同内存;引用一旦绑定变量,终身无法重新绑定
  4. 内存占用:指针占用 4/8 字节(由系统位数决定);引用不占用额外内存空间。
  5. 使用风险:指针易出现空指针、野指针问题;引用安全性高,无野引用。
  6. 使用语法 :指针需配合*解引用、&取地址;引用直接使用,语法更简洁。

高频追问

:引用底层是指针,为什么还要设计引用?

:屏蔽指针的安全隐患,简化书写语法,适合函数传参、返回值等场景。


2. 野指针成因、危害与规避

一、核心成因

  1. 指针未初始化,指向随机未知内存。
  2. 指向的内存被释放(栈变量出作用域、堆内存执行delete/free),指针未及时置空。
  3. 指针访问越界,指向合法内存之外的地址。

二、主要危害

访问非法内存,造成程序崩溃、数据篡改、逻辑错乱。属于未定义行为,问题随机出现,排查难度极大。

三、工程规避方案

  1. 指针定义时直接初始化为nullptr
  2. 内存释放后,立刻将对应指针置空。
  3. 校验指针有效性与数组下标,杜绝越界访问。
  4. 优先使用引用、智能指针替代原生指针。

3. 空指针、空引用详解

3.1 空指针

  • 定义:指向0地址或nullptr的指针,不指向任何有效内存。
  • 特性:语法合法,严禁解引用,解引用会直接导致程序崩溃。
  • 用途:标记指针无有效指向,常用于判空做逻辑分支。

3.2 空引用

  • C++ 语法层面不存在合法空引用,引用定义时必须绑定有效变量。
  • 特殊场景:将空指针强制转为引用,会产生非法引用,本质等同于野指针,运行必然崩溃。

面试结论

空指针语法合法,禁止解引用;空引用不被语法允许,出现即为代码 BUG。


4. 常量指针 vs 指针常量

记忆口诀:看const靠近谁,谁就不能修改

  1. 常量指针 const int* p
    • const修饰指向的内容,指针指向的值不可修改,指针自身地址可修改。
  2. 指针常量 int* const p
    • const修饰指针本身,指针地址不可修改,指向的值可以修改。
  3. 双重 const const int* const p
    • 指针地址、指向内容均不可修改,完全只读。

速记

左定值,右定址const*左侧,值不可改;const*右侧,地址不可改。


5. 多级指针使用场景

核心定义

二级及以上指针,即指向指针的指针,层级代表间接访问的层数。

主流使用场景

  1. 管理动态二维数组、不规则数组。
  2. 函数内修改外部一级指针,需传入二级指针作为参数。
  3. 存储字符串数组,典型用法char**
  4. 底层接口、系统 API 的输出型参数。

补充说明

三级及以上指针可读性极差,工程开发中尽量避免使用。


6. 数组指针与指针数组区分

记忆口诀:看括号内括号归指针,无括号归数组

  1. 指针数组 int* arr[N]
    • 本质:数组 ,数组内每一个元素都是int*类型指针。
    • 用途:存放一组指针、字符串数组。
  2. 数组指针 int (*p)[N]
    • 本质:指针,专门指向长度为 N 的整型数组。
    • 用途:操作、遍历二维数组。

原理补充

运算符优先级:[] 高于 *。无括号时,变量先和[]结合为数组;加括号后,变量先和*结合为指针。


7. 函数指针与回调函数

7.1 函数指针

  • 定义:指向函数的指针,存储函数的入口地址。
  • 作用:可像普通变量一样传递、调用函数。
  • 标准格式:返回值类型 (*指针名)(参数列表)

7.2 回调函数

  • 定义:将函数指针作为参数传入其他函数,由对方在指定时机自动调用该函数。
  • 核心思想:实现代码解耦,分离调用方与功能实现方。

典型场景

事件监听、异步处理、自定义排序规则、第三方库接口、系统底层调用。


8. this 指针底层原理

8.1 基础定义

this是类成员函数隐含形参,指向当前调用该函数的对象本身。

8.2 核心特性

  1. 由编译器自动生成、自动传递,用户不用手动传参。
  2. 存储位置:一般存放在栈区 / 寄存器,不属于对象成员,不占用对象内存。
  3. 静态成员函数没有 this 指针,因为静态函数不属于某个对象。

8.3 作用

  1. 区分成员变量与局部变量 / 形参(解决命名冲突)。
  2. 在成员函数中访问当前对象的成员。
  3. 链式调用返回当前对象 return *this

面试坑点

空对象调用普通成员函数,若函数不访问成员变量,可能不崩溃;一旦通过this访问成员,程序直接崩溃。


9. 指针运算规则

指针运算仅适用于数组 / 连续内存,普通变量指针不建议做运算。

  1. 指针 ± 整数 并非单纯数值加减,而是偏移对应类型的字节大小 。例:int* pp+1 会偏移一个int所占字节。
  2. 指针 - 指针 仅同一块连续内存内合法,计算结果为两个指针之间的元素个数,非字节数。
  3. 指针比较运算 同数组内指针可使用 >, <, == 判断大小,常用于遍历边界判断。

禁止操作

指针之间不能相加、相乘、相除,语法无实际意义,属于非法代码。


10. 指针传参 vs 值传递

1. 值传递

  • 机制:实参拷贝副本传给形参,函数内仅操作副本。
  • 特点:原数据不受影响;大数据拷贝开销大,执行效率低。
  • 适用场景:仅读取数据,无需修改原变量。

2. 指针传参

  • 机制:传递变量内存地址,函数通过地址直接操作原数据。
  • 特点:无需拷贝,效率高;可修改外部实参;存在指针安全风险。
  • 适用场景:需要修改原变量、传递大型对象减少拷贝开销。

补充:引用传参

引用传参等价于指针传参的语法优化,效率一致、安全性更高,工程中优先使用。


🔥 综合高频追问(背诵版)

  1. :数组名和数组首元素指针有什么区别?

    :数组名是常量指针,不能修改指向;普通指针可修改。sizeof(数组名)获取数组总大小,sizeof(指针)固定为 4/8 字节。

  2. :野指针和空指针哪个危害更大?

    :野指针行为随机、崩溃无规律,排查难度远高于空指针,危害更大。

  3. :为什么静态成员函数没有 this 指针?

    :静态成员隶属于类,而非单个对象,因此不需要指向对象的 this 指针。


📝 模块总结

本模块是 C++ 语法根基,围绕指针分类、语法规则、底层原理、工程使用、传参机制展开。吃透全部内容,可应对笔试选择、代码阅读、面试口述中 90% 以上指针相关题目。

相关推荐
YIN_尹1 小时前
【Linux系统编程】基础IO第一讲——系统文件IO
android·java·linux·c++
casual~1 小时前
【学习记录(2)】
c++·学习
苏宸啊10 小时前
IPC管道
linux·c++
BestOrNothing_201510 小时前
ROS2 话题通信实战:消息对象、Publisher 发布器与 Subscriber 订阅器保姆级教程
c++·ros2·subscriber·publisher·话题通信
橘右今11 小时前
2026 Java后端高频面试宝典
java·开发语言·面试
艾iYYY12 小时前
string 类的模拟实现
android·服务器·c语言·c++·算法
为何创造硅基生物12 小时前
C++ virtual void StartNetwork() = 0; // 纯虚:子类必须实现,否则不能 new。
c++
知无不研12 小时前
对套接字的深入理解
linux·服务器·网络·c++·socket·网络套接字
cuso4win13 小时前
Feed 流面试笔记
笔记·面试·职场和发展