第二章|C++ 概述(常考/重要/易错版总结)

目标:用最少的话讲清楚“C++ 是什么、源程序怎么写、程序怎么变成可执行文件、相对 C 扩充了什么、I/O/头文件/注释怎么用”,并标出易错点。

1) C++ 的特点(背诵口径)

  • 编译型 + 强类型:源代码需要编译/链接为可执行文件;类型不匹配会报错/警告。
  • 多范式语言
    • 过程化(函数、结构体)
    • 面向对象(类、封装、继承、多态)
    • 泛型(模板)
  • 性能强、控制力强:可以直接操控内存/指针;代价是更容易出现越界、悬空指针等错误。
  • “C++ = C +(扩展语法)+ 标准库”:很多基础能力依赖标准库(如 iostream、容器等)。

2) C++ 源程序的构成(源文件里必须能看到什么)

典型结构:

  1. 预处理指令#include ...(引库/引头文件)
  2. 声明/定义:常量、变量、函数、类
  3. main():程序入口(必须有)
  4. 语句与语句块 {}:组成控制流程(顺序/分支/循环)

常考提醒

  • main 的常见写法:int main()(返回 int)。
  • return 0; 表示正常结束;有的环境即使不写也会隐式返回 0(但不建议依赖)。

3) 例:计算两个整数之和(最小闭环 + 常错点)

#include <iostream>
using namespace std;
 
int main() {
    int a, b;
    cin >> a >> b;
    cout << a + b << "\n";
    return 0;
}

你必须解释得出的点

  • #include <iostream> 才能用 cin/cout
  • cin >> a >> b; 默认以空白分隔读取。
  • 输出换行更常用 "\n"endl 会额外刷新缓冲区(频繁用可能变慢)。

4) C++ 程序的结构特性(写程序时的“规则感”)

  • main() 开始,通过函数调用组织逻辑(自顶向下)。
  • 块结构 + 作用域:变量的“可见范围”由 {} 决定。
    • 易错:同名变量遮蔽(内层定义会遮住外层)。
    • 易错:局部变量生命周期结束后引用/指针仍在使用(悬空)。
  • 分文件与模块化
    • .cpp:实现(函数体/方法体)
    • .h/.hpp:声明(接口/类型)

5) 编辑—编译—连接—运行(最常考:区分错误发生在哪一步)

一条线

  1. 编辑:写源代码
  2. 预处理:展开 #include、宏替换
  3. 编译:每个 .cpp → 目标文件 .o/.obj
  4. 连接:把多个目标文件 + 库 → 可执行文件
  5. 运行:执行并得到输出

错误定位(非常常考)

  • 编译错误:语法错、类型错、少分号、未声明标识符
  • 连接错误undefined reference(声明了但没定义、漏编译某个 .cpp、漏链接库)
  • 运行错误:崩溃/异常/结果不对(越界、空指针、逻辑问题)

6) C++ 对 C 的“非面向对象扩充”(过程化层面的增强点)

这部分通常考“列举 + 解释作用”:

  • 引用 &:更自然的“别名传参”,常用于函数参数(避免拷贝,语义更安全)。
  • 函数重载:同名函数可用参数列表区分(提高接口表达力)。
  • 默认参数:减少重复重载(但注意声明/定义位置一致)。
  • 灵活的局部变量说明:C++ 允许在语句块中随用随定义变量(更贴近“就近声明、就近初始化”)。
    • 易错:不要在变量声明前使用它;也要注意作用域只在 {} 内。
    int main(){
        int x = 10;
        if (x > 0) {
            int y = x * 2; // 在需要处声明
            // y 只在 if 块内有效
        }
        // y 在这里不可用
    }
  • 结构/联合/枚举名可直接作为类型名
    • 在 C 中常写 struct S s;;在 C++ 中可以直接写 S s;
    struct Node { int v; };
    Node n; // C++:Node 直接是类型名
     
    union U { int i; double d; };
    U u;
     
    enum Color { Red, Green, Blue };
    Color c = Red;
  • const 更严格/更常用:表达“不修改”的契约(常用于形参、指针/引用、常量)。
    • 常考:区分“指向常量的指针”与“常量指针”
    const int* p1 = &x;  // *p1 不能改(指向常量)
    int* const p2 = &x;  // p2 不能改(常量指针)
    const int* const p3 = &x; // 都不能改
    • 建议:能加 const 就加(尤其函数形参用 const T& 传大对象)。
  • 类型安全的 I/Ocin/cout 相比 scanf/printf 更贴近类型系统(但仍可混用)。
  • (可能出现)namespace:解决命名冲突;std:: 就是命名空间使用。

7) 头文件(最易错:重复定义/重复包含)

要点一句话:头文件放“声明”,源文件放“定义/实现”。

  • #include 的本质:文本替换(把头文件内容拷贝进来再编译)。
  • 防重复包含:
    • #pragma once(简单常用)
    • 或 include guard(#ifndef/#define/#endif

易错点(很常见)

  • 在头文件里写了非 inline 的函数定义全局变量定义,多个 .cpp include 后会导致:
    • 连接期重复定义错误(multiple definition)
  • “声明”与“定义”区分:
    • int f(); 是声明
    • int f(){...} 是定义

8) 注释(考法:写法 + 规范)

  • 单行:// 注释
  • 多行:/* 注释 */
  • 建议:注释说明为什么这么做/边界条件/约束,少写“翻译代码”的废注释。

9) 输入输出(常考:空白分隔 vs 整行读取)

  • cin >> x:按空白分隔读取(空格/换行/Tab 都算分隔符)。
  • getline(cin, s):读取一整行(可包含空格)。

易错点

  • cin >> 后紧接 getline,会读到前一次输入留下的换行。
    • 常见处理:先 getline(cin, s); 读掉残留换行,或 cin.ignore()

10) 本章超短总结(考试版)

C++ 是编译型强类型多范式语言;程序以 main() 为入口,源代码经“预处理→编译→连接”生成可执行文件;相对 C 的过程化扩展包括引用、重载、默认参数、const、更类型安全的 I/O 等;头文件负责声明并需防重复包含,I/O 需分清 cin >>getline 的读取规则。

tag:course/oop tag:course/cpp tag:group:Learn