一、编程范式:从“过程驱动”到“对象+过程混合”
- C:纯面向过程
程序以“函数/过程”为核心组织逻辑,数据与操作(函数)分离。比如实现“学生信息管理”,会单独写 input_student() 、 print_student() 等函数,再定义 struct Student 存储数据,数据和函数独立维护。 - C++:面向过程+面向对象
兼容C的过程式编程,同时引入类(class)、对象、继承、多态、封装等面向对象特性。以上述场景为例,C++可以用 class Student 封装成员变量(姓名、年龄)和成员函数( input() 、 print() ),让数据和操作“绑定”,更符合现实世界的抽象逻辑。
二、核心特性对比:C的“简洁” vs C++的“丰富”
- 数据抽象能力
- C:仅支持 struct 组织数据,但 struct 内部不能定义函数,只能通过外部函数操作结构体数据。
- C++: struct 和 class 都可包含成员变量+成员函数,支持“封装”(通过 public/private/protected 控制数据访问权限)。
- 模板与泛型编程
- C:无模板机制,实现“通用逻辑”(比如通用排序)只能依赖宏定义或手动复制代码,无法保证类型安全(宏是文本替换,编译期不做类型检查)。
- C++:提供 template 模板机制,可实现类型安全的泛型编程(比如 std::vector 、 std::vectorstd::string 共用同一套容器逻辑)。
- 命名空间
- C:全局标识符(函数、变量)都在同一命名空间,不同模块的同名元素易发生命名冲突(比如自定义 printf() 会和标准库冲突)。
- C++:引入 namespace ,可将代码按功能分组(比如 namespace MyUtils { void print() {} } ),通过 MyUtils::print() 调用,避免冲突。
- 异常处理
- C:无内置异常机制,错误通过**返回值(如-1表示失败)**或全局变量 errno 报告,错误处理逻辑分散在代码中(每个函数调用后都要检查返回值)。
- C++:提供 try-catch-throw 机制,可在错误处抛出异常、在上层统一捕获处理,减少错误处理的冗余代码。
三、标准库:从“手动造轮子”到“开箱即用”
- C标准库:功能简单,仅提供基础函数(如 strcpy 、 malloc ),复杂功能(动态数组、哈希表)需手动实现。
- C++标准库:兼容C标准库,同时引入STL(标准模板库),包含:
- 容器: std::vector (动态数组)、 std::map (键值对)等;
- 算法: std::sort (排序)、 std::find (查找)等;
大幅降低开发成本,提升代码复用性。
四、内存管理:从“手动控制”到“自动+手动结合”
- C:仅支持手动管理,通过 malloc/calloc 申请、 free 释放内存,易出现内存泄漏(忘记 free )或野指针(释放后继续使用)。
- C++:
- 支持 new/delete 运算符(替代 malloc/free ), new 会自动调用构造函数初始化对象;
- 引入RAII机制:通过对象的构造/析构函数自动管理资源(比如 std::vector 会自动释放内存),减少内存风险。
五、编译与链接:文件后缀与名字修饰
- C:源文件后缀为 .c ,编译器不修改函数名(比如 void func(int) 编译后符号名还是 func )。
- C++:源文件后缀通常为 .cpp/.cc ,编译器会对函数做名字修饰(比如 void func(int) 修饰为 _Z4funci )——这是C++支持函数重载的基础。
注:C++调用C函数需用 extern “C” 声明,避免名字修饰导致链接失败。
六、实战选型:C vs C++怎么选?
- 选C的场景:嵌入式开发(资源受限)、操作系统内核/驱动(追求极致效率)、对代码体积有严格要求的场景。
- 选C++的场景:大型项目(依赖面向对象简化复杂度)、需要STL提升开发效率的场景、游戏/桌面应用等复杂逻辑场景。
总结
C是“轻量、底层、过程式”的语言,适合追求极致控制的场景;C++是C的超集,兼顾底层控制与开发效率,适合复杂项目。理解两者差异,能帮你更合理地选择技术栈。