【C++ 基础】 C++ 与 C 语言差异面试题(附大厂真题解析)
在 C/C++ 开发岗位的面试中,"C++ 与 C 语言的差异" 是高频考点之一。这类问题不仅考察候选人对语言特性的理解,还能反映其编程思维和工程经验。本文精选 10 道经典面试题,涵盖基础语法、面向对象、内存管理等核心差异点,并结合大厂真题进行深度解析,帮助轻松应对面试中的各类挑战。
一、C++ 是不是 C 语言的超集?
高频指数:★★★★★
考察点: 语言特性、历史背景
真题链接: 腾讯 2023 后端开发一面
很多候选人会不假思索地回答 "是",但这恰恰是面试官设置的陷阱。实际上,C++ 并非 C 语言的严格超集,两者存在以下关键差异:
1. 语法差异
- C++ 支持函数重载,而 C 语言不支持
- C++ 的 struct 可以包含成员函数,而 C 语言的 struct 只能包含数据成员
- C++ 引入了引用 (&) 的概念,而 C 语言只有指针
2. 关键字差异
C++ 新增了许多关键字,如class
、namespace
、template
等,这些在 C 语言中是不存在的。
3. 编译差异
- C++ 的变量可以在代码块的任意位置声明,而 C 语言要求变量必须在代码块的开头声明
- C++ 对类型转换的要求更严格,例如 void * 不能隐式转换为其他指针类型
真题解析(腾讯 2023):
面试官问:"C++ 和 C 语言完全兼容吗?请举例说明不兼容的情况。"
参考答案:" 不完全兼容。例如,C++ 中可以这样写:for(int i=0; i<10; i++){...}
,但在 C 语言中必须先声明变量 i。另外,C++ 的 struct 可以包含成员函数,而 C 语言不支持。"
记住 "三不" 原则 —— 语法不完全兼容、关键字不完全相同、编译规则有差异。
二、面向对象特性:C++ 如何实现封装、继承和多态?
高频指数:★★★★★
考察点: 面向对象编程、虚函数、继承机制
真题链接: 阿里 2024 校招研发岗一面
C++ 的面向对象特性是其与 C 语言的核心差异之一。面试官通常会通过以下问题考察候选人的理解:
1. 封装(Encapsulation)
C++ 通过访问控制符(public、private、protected)实现封装,而 C 语言只能通过约定和命名规范来间接实现。
2. 继承(Inheritance)
C++ 支持单继承和多继承,而 C 语言需要通过结构体嵌套来模拟继承。
3. 多态(Polymorphism)
C++ 通过虚函数(virtual function)和运行时类型识别(RTTI)实现动态多态,而 C 语言只能通过函数指针实现静态多态。
真题解析(阿里 2024):
面试官问:"请用代码说明 C++ 的多态是如何实现的?
参考答案:(以下代码示例)
#include <iostream>
using namespace std;class Shape {
public:virtual void draw() { // 虚函数cout << "Drawing a shape." << endl;}
};class Circle : public Shape {
public:void draw() override { // 重写虚函数cout << "Drawing a circle." << endl;}
};int main() {Shape* shape = new Circle();shape->draw(); // 输出:Drawing a circle.delete shape;return 0;
}
关键点:
- 虚函数表(vtable)和虚表指针(vptr)的工作原理
- override 关键字的作用(C++11 引入,确保函数正确重写)
- 动态绑定与静态绑定的区别
三、内存管理:new/delete vs malloc/free
高频指数:★★★★★
考察点: 内存分配、构造函数、异常处理
真题链接: 字节跳动 2023 社招 C++ 开发岗二面
这是面试中的必问题,不仅要知道语法差异,还要深入理解底层机制:
对比项 | new/delete | malloc/free |
---|---|---|
数据类型 | 内置类型和自定义类型 | 仅处理内存块 |
构造 / 析构 | 自动调用构造函数和析构函数 | 需要手动管理对象生命周期 |
返回值类型 | 直接返回对象指针 | 返回 void*,需要显式类型转换 |
内存分配失败 | 抛出 std::bad_alloc 异常 | 返回 NULL |
重载可能性 | 可以重载 new/delete 操作符 | 无法重载 |
真题解析(字节跳动 2023):
面试官问:"在 C++ 中,什么情况下使用 malloc/free 比 new/delete 更合适?"
参考答案:在与 C 代码交互时,或者需要精确控制内存分配大小和对齐方式时,malloc/free 可能更合适。例如,在实现内存池时,我们通常使用 malloc/free 管理内存块。
深度扩展:
- 定位 new(placement new)的使用场景
- 自定义 new/delete 操作符的实现方法
- 智能指针如何解决内存泄漏问题
四、const 关键字:C++ 与 C 语言的差异
高频指数:★★★★☆
考察点: 常量修饰、指针与引用、底层实现
真题链接: 百度 2023 校招软件开发岗三面
C++ 中的 const 比 C 语言更强大,主要体现在以下方面:
1. 常量定义
- C++ 的 const 常量必须在定义时初始化,而 C 语言可以后赋值
- C++ 的 const 常量默认具有内部链接属性(只在当前文件可见)
2. 指针与引用
- C++ 支持常量引用(const T&),常用于函数参数传递
- C++ 的顶层 const 和底层 const 区分更严格
3. 类成员函数
- C++ 允许在类成员函数声明后添加 const,表示该函数不会修改对象状态
真题解析(百度 2023):
面试官问:" 请解释 C++ 中 const int和 int const 的区别。"
参考答案:const int是指向常量的指针,指针本身可以修改,但不能通过指针修改所指向的值;int const 是常量指针,指针本身不能修改,但可以通过指针修改所指向的值。
看 const 离谁近,离变量名近就是常量指针,离类型近就是指向常量的指针。
五、结构体(struct)与类(class)的区别
高频指数:★★★★☆
考察点: 访问控制、默认继承权限、内存布局
真题链接: 微软 2024 校招 SDE 一面
在 C++ 中,struct 和 class 的主要区别如下:
对比项 | struct | class |
---|---|---|
默认访问权限 | public | private |
默认继承权限 | public | private |
用途 | 主要用于数据聚合 | 主要用于面向对象编程 |
模板支持 | 完全支持 | 完全支持 |
真题解析(微软 2024):
面试官问:"在 C++ 中,struct 和 class 的内存布局有什么不同?"
参考答案:在 C++ 中,struct 和 class 的内存布局原则上是相同的,都遵循成员对齐规则。但如果 struct 或 class 包含虚函数,编译器会为其添加虚函数表指针,这可能影响内存布局。
深度扩展:
- C++11 引入的标准布局类型(Standard Layout Type)
- 空类(empty class)的大小为什么是 1 字节
- 结构体的内存对齐规则与优化方法
六、函数重载(Function Overloading)与默认参数
高频指数:★★★☆☆
考察点: 名字修饰(Name Mangling)、重载决议规则
真题链接: 美团 2023 校招后端开发岗二面
函数重载是 C++ 的重要特性,而 C 语言不支持。需要注意以下关键点:
1. 重载条件
- 函数名相同,但参数列表不同(参数个数、类型或顺序)
- 返回值类型不能作为重载的依据
2. 默认参数
- C++ 允许函数参数设置默认值,但要注意避免二义性
- 默认参数只能出现在函数声明或定义的其中一处
3. 名字修饰(Name Mangling)
- C++ 编译器通过名字修饰实现函数重载,而 C 语言直接使用函数名
真题解析(美团 2023):
面试官问:"以下代码是否合法?为什么?"
void func(int a, double b = 3.14); void func(int a); // 重载声明
参考答案:不合法。因为第二个函数声明与第一个函数的默认参数版本产生了二义性。当调用 func (1) 时,编译器无法确定应该调用哪个函数。
七、C++ 的异常处理机制
高频指数:★★★☆☆
考察点: try-catch 块、异常类层次、RAII
真题链接: 网易 2024 校招游戏开发岗一面
C++ 的异常处理机制是其与 C 语言的重要差异之一:
1. 基本语法
try {// 可能抛出异常的代码
} catch (const std::exception& e) {// 异常处理代码
}
2. 异常类层次
C++ 标准库提供了一套异常类层次,基类是 std::exception,常见派生类包括:
- std::bad_alloc(new 失败时抛出)
- std::out_of_range(越界访问时抛出)
- std::runtime_error(运行时错误)
3. 异常安全保证
- 基本保证:异常发生后,对象处于有效状态
- 强保证:异常发生后,程序状态回滚到调用前
- 不抛异常保证(noexcept):函数不会抛出异常
真题解析(网易 2024):
面试官问:"C++ 的异常处理机制相比 C 语言的错误返回码有什么优势?"
参考答案:异常处理机制使错误处理代码与正常业务逻辑分离,提高了代码可读性;同时,异常可以跨函数边界传播,避免了多层嵌套的错误检查。此外,异常处理与 RAII 技术结合,可以确保资源的正确释放。
深度扩展:
- noexcept 关键字的使用场景和性能影响
- 异常规范(Exception Specification)的演变(从 throw () 到 noexcept)
- 异常处理的开销分析
八、引用(Reference)与指针(Pointer)的区别
高频指数:★★★★☆
考察点: 底层实现、使用场景、空值处理
真题链接: 谷歌 2023 社招资深 C++ 工程师三面
引用是 C++ 引入的新概念,与指针有本质区别:
对比项 | 引用 | 指针 |
---|---|---|
定义 | 变量的别名 | 存储内存地址的变量 |
初始化 | 必须初始化,且不能重新绑定 | 可以不初始化,且可以重新赋值 |
空值 | 不能为 NULL | 可以为 NULL |
操作符 | 使用直接操作符(如 =、+) | 使用间接操作符(如 *、->) |
多级 | 不支持多级引用 | 支持多级指针 |
sizeof | 返回引用对象的大小 | 返回指针本身的大小 |
真题解析(谷歌 2023):
面试官问:"在函数参数传递中,什么时候应该使用引用而不是指针?"
参考答案:当不允许参数为 NULL,且不需要重新绑定到其他对象时,应优先使用引用。例如,STL 算法的参数通常使用引用传递。另外,在重载操作符时,引用往往是更合适的选择。
引用是 "别名",指针是 "地址";引用必须初始化,指针可以为空。
九、C++ 的输入 / 输出流(iostream)与 C 的标准 IO(stdio)
高频指数:★★★☆☆
考察点: 类型安全、扩展性、性能
真题链接: 腾讯 2024 校招技术研究岗一面
C++ 的 iostream 与 C 的 stdio 有以下主要区别:
1. 类型安全
- iostream 通过重载操作符 <<和>> 实现类型安全的输入输出
- stdio 使用格式化字符串(如 % d、% s),需要手动指定类型
2. 扩展性
- iostream 支持自定义类型的输入输出,只需重载 <<和>> 操作符
- stdio 扩展困难,需要使用自定义格式化函数
3. 性能
- 一般情况下,stdio 的性能略高于 iostream
- iostream 的缓冲机制可以通过 sync_with_stdio (false) 优化
真题解析(腾讯 2024):
面试官问:"cout << endl 和 cout << '\n' 有什么区别?"
参考答案:endl 不仅输出换行符 '\n',还会刷新输出缓冲区(调用 flush ()),这可能影响性能。而 cout << '\n' 只输出换行符,不会强制刷新缓冲区。
深度扩展:
- 自定义流操作符的实现方法
- 文件流(fstream)和字符串流(stringstream)的使用场景
- C++20 引入的 format 库对传统 IO 的改进
十、命名空间(Namespace)的作用与使用
高频指数:★★★☆☆
考察点: 命名冲突、嵌套命名空间、using 声明
真题链接: 字节跳动 2023 校招后端开发岗三面
命名空间是 C++ 解决命名冲突的重要机制:
1. 基本语法:
namespace MyNamespace {void func() { /* ... */ }
}// 使用命名空间中的成员
MyNamespace::func();
2. using 声明
- using namespace:引入整个命名空间
- using 声明:只引入特定成员
3. 嵌套命名空间
C++ 允许命名空间嵌套,形成层次结构:
namespace A {namespace B {void func() { /* ... */ }}
}// 等价于A::B::func()
using namespace A::B;
func();
真题解析(字节跳动 2023):
面试官问:"在头文件中使用 using namespace std; 有什么风险?"
参考答案:在头文件中使用 using namespace std; 会将 std 命名空间的所有内容引入全局命名空间,可能导致命名冲突。更好的做法是在源文件中使用 using 声明,或者直接使用完整的命名空间限定。
命名空间防冲突,头文件慎用 using。
总结与实战建议
1. 面试应答技巧
- 回答问题时,不仅要说出差异,还要结合实际场景说明优缺点
- 对于代码示例类问题,先理清思路,再写出清晰、规范的代码
- 遇到不确定的问题,不要急于回答,可以请求面试官给予提示
2. 复习建议
- 结合《C++ Primer》《Effective C++》等经典书籍深入理解语言特性
- 多做面试真题,总结高频考点和答题模式
- 动手实现一些小项目,加深对 C++ 特性的实际应用理解
3. 进阶学习资源
- C++ 标准库文档:https://en.cppreference.com/w/
- 开源项目学习:STL 源码、Boost 库等
- 技术社区:Stack Overflow、知乎、GitHub 等
你在面试中遇到过哪些关于 C++ 与 C 语言差异的有趣问题?欢迎在评论区分享你的经历和解题思路!
如果你觉得这篇文章对你有帮助,请点赞、收藏并分享给更多需要的朋友。后续我们还会推出更多关于 C++ 面试的深度内容,敬请期待!