CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
C++ 语言入门/课时/C++ 是什么
RawBlame
课时目录12 节

C++ 语言入门

  1. 01C++ 是什么
  2. 02基础语法
  3. 03指针与引用
  4. 04面向对象
  5. 05内存与 RAII
  6. 06STL 容器与算法
  7. 07模板基础
  8. 08现代 C++ 特性
  9. 09多线程
  10. 10构建与依赖
  11. 11调试与测试
  12. 12综合练习

C++ 是什么

c-vs-c、why-use-c、环境、第一个程序。

25 分钟

C++ 是什么

这一课你将能做到

  1. 说清楚 C++ 的编译执行模型,以及它和 Java「编译成字节码 + JVM 运行」的本质区别
  2. 在本机确认 g++(或 MSVC/clang)可用,手动编译并运行第一个 C++ 程序
  3. 读懂一个最小 C++ 程序的每一行:#include、main、std::cout 各自在做什么

为什么要学

本站的在线判题功能,判题沙箱本身就是 C++ 写的:拿到用户提交的代码后,要毫秒级完成「编译 → 起进程 → 跑测试点 → 回收资源」,每一步都压着性能红线,这正是 C++ 的主场。游戏引擎、高频交易、嵌入式、数据库内核,用的也是同一套逻辑。

如果你已经会 Java:C++ 没有 JVM,也没有垃圾回收。Java 源码编译成 .class 字节码交给 JVM 解释/JIT 执行;C++ 源码直接编译成目标平台的机器码,操作系统直接加载运行。这带来两个后果:一是 C++ 程序跑起来更快、内存更省;二是跨平台要「每个平台各编译一次」,不像 Java 一次编译到处运行。

本轨对齐 C++17/20 标准,不背标准条文,只练能写进真实项目的默认习惯。

先建立图像

Java 的路径:
  .java → javac → .class 字节码 → JVM(解释 + JIT)→ CPU
                                     ↑ 运行时还在干活

C++ 的路径:
  .cpp / .hpp → 预处理 → 编译 → 汇编 → 链接 → 可执行文件 → CPU
                ↑ 这四步在运行前全部做完,运行时没有任何「中间商」

判题沙箱评测用户代码时,本质上就是替用户走一遍右边这条流水线,再掐表计时——所以理解编译模型,是理解「C++ 为什么快」的第一步。

跟着做

步骤 1:确认编译器

Windows 推荐 MinGW-w64(或 VS + C++ 工作负载),macOS 用 xcode-select --install,Linux 用 sudo apt install g++。打开终端验证:

g++ --version

能打印出版本号(如 g++ (MinGW-w64) 13.2.0)就说明环境通了。判题沙箱内部同样会先探测编译器版本再决定编译参数。

步骤 2:写第一个程序

新建文件夹 cpp-lab,在里面新建 hello.cpp:

#include <iostream>

int main() {
    std::cout << "Hello, C++!" << std::endl;
    return 0;
}

步骤 3:编译并运行

在终端里(进入 cpp-lab 目录):

g++ -std=c++17 hello.cpp -o hello
./hello        # Windows 下是 .\hello.exe 或 hello

输出:

Hello, C++!

这条命令做了四件事:预处理(展开 #include <iostream> 的全部内容)→ 编译成汇编 → 汇编成目标文件 → 链接标准库,最终生成一个可以直接运行的可执行文件。-std=c++17 指定按 C++17 标准编译,本轨全程带上它。

步骤 4:逐行理解

#include <iostream>   // 预处理指令:把输入输出库的头文件「复制粘贴」进来
                      // C++ 的 include 是文本替换,不是 Java 的 import

int main() {          // 程序入口。操作系统加载可执行文件后从 main 开始执行
    std::cout << "Hello, C++!" << std::endl;
    // std::cout 是标准输出流对象,<< 是流插入运算符,可以连续拼接
    // std:: 是命名空间,表示这个名字属于标准库——相当于 Java 的包名
    // std::endl 输出换行并刷新缓冲区;"\n" 只换行不刷新,更快
    return 0;         // 返回 0 表示程序正常结束,非 0 是错误码
}

对比 Java:System.out.println("Hello") 和 std::cout << ... 干的是同一件事,只是 C++ 用运算符重载实现了流式输出。

步骤 5:体会「编译型」的含义

故意写一个错误:

int main() {
    int x = "hello";   // 类型不匹配
}

编译:

g++ -std=c++17 hello.cpp -o hello

你会得到类似 error: invalid conversion from 'const char*' to 'int' 的编译错误,可执行文件根本不会生成。Java 也有编译检查,但 C++ 的检查发生在机器码生成之前,报错信息更底层、也更「凶」。读编译错误是 C++ 初学者的必修课,本轨每一课都会带你读。

步骤 6:看一眼机器码长什么样(可选)

g++ -std=c++17 -S hello.cpp    # 生成 hello.s 汇编文件

打开 hello.s 能看到一堆 mov、call 指令——这才是 CPU 真正执行的东西。Java 字节码是给 JVM 看的,C++ 汇编是给 CPU 看的,差别的根源就在这里。

讲清楚要点

  1. 编译期 vs 运行期:C++ 把大量工作(类型检查、模板实例化、内联优化)压到编译期,换来运行期零开销。这是 C++ 性能优势的总根源。
  2. #include 是文本复制:它不是「引入类路径」,而是真的把头文件内容原样粘进当前文件。所以头文件里放声明、源文件里放实现,能避免重复编译。
  3. main 是唯一入口:每个可执行程序必须有且只有一个 main。多文件工程里,其他文件只提供函数和类,不写 main。
  4. 标准库都在 std 命名空间里:std::cout、std::string、std::vector。初学阶段建议写全 std:: 前缀,不推荐 using namespace std;——它会污染命名空间,判题沙箱这类大项目更是明令禁止。
  5. C++ 是 C 的超集(大体上):C 的语法基本都能在 C++ 里编译通过,所以你会同时见到 C 风格(printf、裸指针)和 C++ 风格(iostream、引用)两种写法。本轨只教现代 C++ 风格。

你可能会懵的地方

  • C、C++、Java 到底什么关系? C 诞生于 1972 年,贴近硬件;C++ 在 C 上加了类、模板、标准库(1983 年命名);Java 借鉴 C++ 语法但砍掉指针运算、多继承,换上 JVM 和 GC。语法上三者相似,运行模型上 C/C++ 编译成机器码,Java 编译成字节码。

  • 为什么 .cpp 和 .hpp 要分开放? .hpp(或 .h)是头文件,放「声明」:函数签名、类定义,给别人 #include 用;.cpp 放「实现」。这样改实现只重编译一个 .cpp,改声明才触发大规模重编译。Java 没有这个区分,一个 .java 文件全包了。

  • endl 和 "\n" 有什么区别? 都换行,但 endl 额外刷新输出缓冲区(立即显示),频繁使用会拖慢输出。判题沙箱要输出大量测试结果时都用 \n。默认用 "\n",需要实时看输出时用 endl。

  • C++17、C++20 是什么? ISO 标准的年份版本,每三年一发。C++11 是现代 C++ 的分水岭(智能指针、lambda、auto 都是它引入的),C++17 加了结构化绑定、std::optional,C++20 加了概念、范围库。本轨以 C++17 为主,穿插 C++20 实用特性。

  • 为什么 C++ 编译比 Java 慢这么多? 编译期要做的事多得多:模板实例化、头文件层层展开、跨文件优化。Java 把这些推迟到类加载和 JIT 阶段。所以判题沙箱给每道题设了编译时限,超时直接判编译失败。

错法对照

错法问题正解
#include <iostream.h>老 C++ 写法,现代编译器没有这个头文件#include <iostream>
直接双击 .cpp 文件想运行.cpp 是源码,不是可执行文件先 g++ xxx.cpp -o xxx 编译再运行
文件路径含中文或空格就报错部分编译器/终端对路径处理不稳工程路径全英文、无空格
每个文件都写 using namespace std;命名冲突风险,工程禁忌显式写 std:: 前缀
void main()非标准写法,部分编译器拒绝恒用 int main()

卡点急救

  1. g++ 不是内部或外部命令:编译器没装或没加 PATH。Windows 下把 MinGW 的 bin 目录加入环境变量 PATH 后重开终端。
  2. undefined reference to 'main':链接阶段没找到入口。检查是否忘了写 main 函数,或编译命令里漏掉了含 main 的那个 .cpp 文件。
  3. Windows 控制台中文乱码:源文件保存为 UTF-8,并在编译时加 -fexec-charset=GBK(MinGW),或先执行 chcp 65001 切换控制台编码。

面试常问

  • C++ 编译执行和 Java 解释执行的区别? C++ 直接编译为目标平台机器码,运行时无虚拟机开销,启动快、性能高,但需按平台分别编译;Java 编译为字节码由 JVM 加载,通过解释器 + JIT 达到接近原生的性能,换来跨平台与运行时管理(GC、反射)。二者是「编译期优化」与「运行期优化」的取舍。

  • 从源码到可执行文件经历哪几个阶段? 预处理(宏展开、头文件包含)→ 编译(生成汇编)→ 汇编(生成目标文件 .o)→ 链接(合并目标文件与库,解析符号引用)。常考链接阶段报错 undefined reference 与编译阶段报错 no member named 的区别。

  • 为什么在线判题系统常用 C++ 写沙箱? 判题要精确计量用户程序的 CPU 时间和内存,沙箱本身必须零干扰:C++ 编译成原生代码无 GC 停顿、无 JVM 开销,且能用系统调用直接做进程隔离、资源限额(如 setrlimit),延迟和可控性都最优。

自测三问

  1. 从 .cpp 到可执行文件要经过哪四个阶段?
  2. #include 和 Java 的 import 有什么本质区别?
  3. 为什么不推荐 using namespace std;?

小结一句话

C++ 把一切压到编译期:源码直接变成机器码,没有 JVM 中间商,换来极致性能和手动资源管理——理解编译模型,就理解了 C++ 与 Java 的分野。

延伸

  • cppreference:C++ 编译过程
  • cplusplus.com:C++ 教程首页
  • 下一课:基础语法——变量、控制流与函数。
加载本节练习…
下一课 →基础语法