C++ 最初是在 C 语言的基础上扩充而来的,两门语言的名字非常相近,基础语法也有不少重合之处。
但在实际开发中,C 和 C++ 早已发展成两门各自拥有独立标准、日常写法差异明显的编程语言。在起步阶段先把它们之间的联系与区别理清楚,可以帮我们少走很多弯路。
C++ 和 C 是什么关系?
C++ 和 C 语言的关系,可以用一句话来概括:C++ 源自 C 语言,保留了大量相似的基础语法,但现代 C++ 并不是 “C 语言再加几个新功能” 这么简单。
像后面我们将要学习的变量、条件判断、循环、函数、数组以及指针等基础语法,在两门语言里长得非常像。学过 C 语言的小伙伴再看 C++,会觉得基础代码很眼熟。反过来,学完 C++ 之后再去读基础的 C 语言代码,也不会感到陌生。
不过这里小伙伴们不要误解了:基础语法相似,并不代表两门语言完全兼容,也不代表 “所有 C 代码都能直接当成 C++ 代码来运行”。它们就像同根生的两门近亲语言,各自都在独立发展,而不是同一门语言换了个新名字。
“C 语言超集” 的说法
网上常有一种说法:“C++ 是 C 语言的超集,也就是 C 语言的全部内容加上一些新功能。” 实际上这样理解并不准确,因为两门语言在类型检查和语法细节上已经存在不少差异。
比如 class 和 new 在 C 语言里只是普通单词,写成 int class = 1; 完全合法。但在 C++ 中,它们属于专门保留的关键字,拿来当变量名就会直接编译报错。因此,初学阶段直接把 C++ 当成一门独立的语言来学才是最稳妥的。
C++ 与 C 的主要区别
如果把两门语言的所有细节都拿出来对比,完全可以写成一本厚厚的手册。对于初学者来说,我们可以先重点抓住下面这 5 个方面的差异,如下表所示。
| 对比维度 | C 语言 | C++ |
|---|---|---|
| 编程思想 | 以面向过程为主 | 支持面向过程、面向对象、模板编程等多种方式 |
| 标准库工具 | 小巧精简,仅提供基础输入输出与内存操作 | 丰富实用,自带字符串、动态数组、排序算法等 |
| 常用输入输出 | 主要使用 scanf() 和 printf() | 主要使用 std::cin 和 std::cout |
| 类型与语法扩展 | 语法规则精简,类型检查相对宽松 | 类型检查更严格,新增引用、函数重载、模板等 |
| 内存管理方式 | 主要依赖手动申请与手动释放 | 支持结合智能指针等工具自动管理内存 |
1. 编程思想不同
C 语言是一门经典的 “面向过程” 编程语言。编写 C 语言代码时,重点在于按步骤拆分任务,就像照着菜谱做菜一样:第一步处理什么数据,第二步调用哪个函数,所有代码都围绕 “执行步骤” 来展开。
C++ 在完整保留面向过程写法的同时,还支持 “面向对象” 编程。拿开发游戏来说,如果代码只有几百行,按步骤写几个函数就够用了。但如果项目有几十万行代码,使用 C++ 的 “类(class)” 把游戏角色的属性和技能打包在一起管理,整体结构就会清晰得多。
当然了,写 C++ 并不是非要把所有代码都塞进 “类” 里不可。普通函数和按步骤执行的代码,依然是 C++ 日常开发最常用的基础部分。
2. 标准库与日常写法不同
C 语言自带的标准库非常精简,主要提供基础的输入输出、字符处理和内存操作。遇到稍微复杂一点的需求,比如动态调整数组大小或拼接两段文字,往往需要我们自己手写不少底层代码。
现代 C++ 的标准库则丰富得多,像字符串、动态数组、排序和查找算法等常用工具都已经内置好了。这也直接决定了两门语言日常写出来的代码有很大差异。
举个简单的例子,同样是往屏幕上输出一句话,C 语言通常使用 printf() 函数:
printf("Hello!\n");而在 C++ 中,我们通常使用标准库的 std::cout 配合 << 符号:
std::cout << "Hello!\n";再比如,当我们需要在程序里保存并拼接两段文字时,现代 C++ 可以直接使用标准库的 std::string 来处理字符串。下面我们来看一个例子。
示例:C++ 拼接字符串
#include <iostream>
#include <string>
int main() {
std::string a = "Hello, "; // 定义第 1 个字符串
std::string b = "lvyenet!"; // 定义第 2 个字符串
std::cout << a + b << "\n"; // 拼接并输出
return 0;
}运行结果如下。
Hello, lvyenet!分析:
在这个例子中,我们先通过 #include <string> 引入了字符串工具箱,接着定义了 a 和 b 两个 std::string 变量。想要把两段文字拼在一起,直接使用 + 号写成 a + b 就可以了,非常直观。
如果换成 C 语言,是不能直接使用 + 号拼接文字的,通常需要写成下面这样:
char a[20] = "Hello, ";
char b[] = "lvyenet!";
strcat(a, b);
printf("%s\n", a);哪怕你之前没学过 C 语言也没关系,单看步骤就能看出差别:C 语言不仅要手动写上 a[20] 提前预留空间,还得调用专门的 strcat() 函数去拷贝拼接,一旦空间算小了程序就可能出错。
而在 C++ 中,直接写 a + b 就能自动分配空间并把两段文字拼好,日常写起来要省心很多。
提示 在日常开发中,我们可以通过文件后缀名快速区分这两门语言的代码:C 语言源文件一般以 .c 结尾,比如 main.c;C++ 源文件一般以 .cpp 结尾,比如 main.cpp。
3. 类型检查不同
C 语言的语法规则相对宽松,有些类型不太匹配的含糊写法只给出警告也能勉强编译通过。而 C++ 对数据类型的检查严格得多,一旦发现类型对不上,编译器在编译阶段就会直接报错,帮我们把潜在隐患提前找出来。
此外,C++ 还在 C 语言的基础上增加了引用、函数重载和模板等实用语法,方便我们编写更加安全、通用的代码,不必为相似的功能重复写多份逻辑。
4. 内存管理不同
在内存管理方面,C 语言申请和释放内存基本全靠手动配对完成。一旦程序复杂起来,忘记释放已经不用的内存,就容易导致内存被持续占用,也就是常说的 “内存泄漏”。
而在现代 C++ 中,除了保留底层内存控制能力之外,我们还可以借助智能指针等工具,让程序在用完内存后自动清理干净。
C 和 C++ 应该怎么选?
虽然 C++ 的功能更丰富,但并不意味着 C++ 把 C 语言淘汰了。在实际工作中,这两门语言有着各自明确的分工,我们可以根据自己的学习目标,从以下 2 个方向来选择:
- 优先选择 C 语言的场景:如果你的明确目标是做 Linux 等操作系统内核、硬件驱动程序,或者给 51、STM32 等内存很小的单片机编写底层控制程序,那么 C 语言依然是首选。
- 优先选择 C++ 的场景:如果你的目标是开发大型游戏与游戏引擎、桌面客户端软件、自动驾驶与机器人控制、高性能后端服务、人工智能底层框架,或者参加 CSP、NOIP、ACM 等算法竞赛,那么直接学习 C++ 就可以了。
常见问题
1. 学习 C++ 之前,需要先学 C 语言吗?
不需要。如果你的目标就是掌握 C++,直接从零开始学 C++ 是最省时间的路线。像变量、条件判断、循环、函数、数组和指针这些共有的基础语法,本身就是 C++ 自己的组成部分,后面都会在 C++ 语境下从头讲透。
相反,如果先花几个月去学 C 语言,反而容易养成到处使用 C 风格字符数组和手动管理内存的旧习惯,后续还得花力气改过来。
2. 在 C++ 程序中,还能使用 C 语言的 printf() 等函数吗?
语法上是支持的,因为 C++ 兼容了绝大部分 C 语言标准库功能。不过在编写现代 C++ 代码时,我们更推荐优先使用 std::cout 和 std::string 等 C++ 自带工具,不仅不用死记繁琐的格式符号,类型检查也更加安全。
