从 C 到 C++:核心过渡笔记(适合有 C 基础、刚开始系统学习 C++ 的人)
这是一份高度浓缩的“从 C 思维切换到 C++ 思维”的对比式笔记,重点放在最重要、最容易混淆、最影响后续学习的差异上。
1. 必须先转变的五大核心思维
| 排名 | C 思维(常见写法) | C++ 推荐思维(现代写法) | 为什么重要(一句话) |
|---|---|---|---|
| 1 | 用 malloc / free 手动管理内存 | 优先使用 RAII 类(vector、string、unique_ptr 等) | 90% 的内存泄漏和野指针问题直接消失 |
| 2 | 用 struct + 函数指针模拟对象 | 直接写 class / struct + 成员函数 | 代码可读性、封装性、维护性指数级提升 |
| 3 | 用 char* / char 数组处理字符串 | 默认用 std::string | 安全性、便利性、性能综合碾压 |
| 4 | 函数返回值表示成功/失败 + 输出参数传结果 | 用异常 / std::optional / std::expected(C++23) | 接口更清晰,调用方代码更简洁 |
| 5 | 全局变量、宏定义到处飞 | 尽可能用 const / constexpr / 命名空间 / enum class | 可维护性、可测试性、模块化能力大幅提高 |
2. 最常出错的 12 个过渡陷阱(带正确写法)
| 序号 | C 风格写法(容易出错) | C++ 现代写法(强烈推荐) | 关键差异说明 |
|---|---|---|---|
| 1 | char buf[256]; scanf("%s", buf); | std::string s; std::cin >> s; 或 std::getline(std::cin, s); | 缓冲区溢出风险彻底消失 |
| 2 | char* p = (char*)malloc(n); ... free(p); | std::vector<char> v(n); 或 std::unique_ptr<char[]> p(new char[n]); | 自动析构、边界检查、类型安全 |
| 3 | struct Node { int val; struct Node* next; }; | struct Node { int val; Node* next = nullptr; }; | 默认初始化 + 成员初始化列表更安全 |
| 4 | #define MAX(a,b) ((a)>(b)?(a):(b)) | inline auto max(auto a, auto b) { return a>b?a:b; } 或 std::max | 类型安全、调试容易、可打断点 |
| 5 | int cmp(const void* a, const void* b) | bool cmp(const Type& a, const Type& b) 或 lambda | 可读性、类型安全、泛型能力 |
| 6 | typedef struct { ... } Stu; | using Stu = struct { ... }; 或直接 struct Stu { ... }; | C++ 中 struct 已经是完整类型名 |
| 7 | FILE* fp = fopen(...); if(!fp) ... fclose(fp); | std::ifstream ifs(filename); if(!ifs) ... | RAII 自动关闭、异常安全 |
| 8 | void swap(int* a, int* b) | void swap(int& a, int& b) 或 std::swap | 更直观,不用取地址 |
| 9 | int* arr = (int*)malloc(sizeof(int)*n); | std::vector<int> arr(n); 或 std::unique_ptr<int[]> arr(new int[n]); | 长度自带、边界安全、自动释放 |
| 10 | enum Color { RED, GREEN, BLUE }; | enum class Color { Red, Green, Blue }; | 强类型枚举,不会隐式转换到 int |
| 11 | 全局变量 int g_count; | 命名空间内 static 变量 或 函数内 static | 降低全局污染、更好的封装 |
| 12 | void* memmove(void* dest, const void* src, size_t n) | std::copy / std::move / 容器算法 | 类型安全、表达力更强 |
3. 过渡期推荐的“写代码三原则”(强烈建议贴屏幕上)
- 能用 std 容器就别自己写链表/数组/字符串
vector / string / unordered_map / set 是前三年最该熟练的四个家伙 - 能用引用就别用指针,能用 const 引用就别用值传递
void print(const std::string& s); // 好
void print(std::string s); // 不好(拷贝)
void print(const char* s); // 能避免就避免
- 能用 RAII 管理资源就别手写配对的 new/delete、malloc/free、fopen/fclose
std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(...), fclose);
// 或更简单:
std::ifstream ifs("data.txt");
4. 推荐的学习路径(0→能写现代 C++)
| 阶段 | 时间建议 | 核心任务 | 推荐练习题/项目 |
|---|---|---|---|
| 阶段1 | 1–2 周 | 熟练 vector / string / cin/cout / 范围for | 字符串处理、简单OJ题(读入→处理→输出) |
| 阶段2 | 2–3 周 | 理解 RAII、智能指针、const & constexpr | 用 unique_ptr / shared_ptr 重写链表、树 |
| 阶段3 | 3–4 周 | 函数重载、引用、默认参数、类初步 | 实现简易 vector / string / stack / queue |
| 阶段4 | 持续进行 | 模板 + STL 常用算法 + lambda | 用 STL 解决 100 道经典算法题 |
5. 一张“速查表”:C → C++ 常见替换对照
| C 写法 | C++ 推荐写法 | 备注 |
|---|---|---|
char buf[1024]; | std::string buf; | 长度自适应 |
strcpy / strcat / strcmp | = += == | 更安全、更简洁 |
malloc(n * sizeof(T)) | std::vector<T> v(n); | 首选 |
(T*)malloc(sizeof(T)) | std::make_unique<T>() 或 std::unique_ptr<T>(new T) | 智能指针 |
struct + 函数指针 | class / struct + 成员函数 | 面向对象基础 |
#define 常量 | constexpr 或 const | 编译期检查 |
enum | enum class | 强类型 |
void* | 模板 或 std::any / std::variant | 类型安全 |
祝你从 C 顺利过渡到现代 C++!
有哪一部分你希望我再展开详细代码示例?
(比如:用 RAII 风格重写链表、智能指针实现简易 unique_ptr、string 的几种常见陷阱等)