C++期末复习指南:从指针到面向对象的高频考点与走查技巧

C++期末复习指南:从指针到面向对象的高频考点与走查技巧 简介这是一份东北林业大学《C程序设计》课程期末考试试卷适合正在系统复习C语法、面向对象编程及STL用法的本科生和自学人群。试卷考核范围覆盖基础语法、函数与递归、指针与动态内存、数组与字符串、结构体与联合体、类与对象、继承与多态、模板、STL容器与算法、异常处理以及文件I/O等核心章节可用于模拟自测、考前冲刺和查漏补缺。资源为单个PDF文件整体压缩包仅160KB清晰易读便于电脑、平板或手机随时翻阅。该试卷已吸引超过1000人学习下载说明内容贴近许多高校C课程的常见考点。借助这套试卷读者既能熟悉期末考试题型与命题侧重也能对照题目检验自己对指针、虚函数、容器等易错难点的掌握程度并针对薄弱环节进行专项强化是高性价比的期末复习资料。1. 一份 C 期末考试试卷能把“会敲代码”和“真会”分得很清楚每到期末总有人到处找「东北林业大学《C程序设计》期末考试试卷.pdf」这类资料。真拿到手多半会失望试卷没几页题目看着都眼熟可合上 IDE 手写答案立刻有人露怯——考场上没人替你指出少了个分号。程序设计基础课的期末卷命题范围相当固定语法细节、指针数组、面向对象、流 I/O 与文件读写再加两三道经典算法手写题。难点不在深度在密度一次构造析构顺序判断错、一个 const 漏写就是三五分的差距。下面这份复习路线适合正在备考 C 期末的本科生也适合带课助教用来划重点。先拆题型分布再过高频考点最后给一套不依赖编译器的走查法按这个路子练比多刷十份试卷更划算。2. 从题型分布推演 C 程序设计期末卷阅读程序与手写代码的复习权重把试卷当“知识点清单”复习是低效的按题型复习才贴近真实得分结构。多所理工科院校程序设计基础课的期末卷题型构成高度一致分值有浮动但骨架稳定先看这张分布表。2.1 选择题与填空指针用法和默认参数是命题密度最高的语法点题型常见分值考查重心复习优先级选择题2030语法细节、指针用法、运算符优先级高填空题1020输出结果、参数传递、类成员访问高阅读程序写结果1525构造析构顺序、重载解析、静态成员极高程序设计题2035排序查找、字符串处理、文件读写极高选择题最爱考一组“近亲”*p与(*p)的区别、const int *p与int *const p的区别、函数重载的匹配顺序、默认参数必须从右往左连续给出。这些都能背成结论属于典型的 C 八股不背熟就会在考场上犹豫三五分钟。#include iostream int main() { int a[5] {1, 2, 3, 4, 5}; int *p a; std::cout *p ; // 先取 *pp 再后移 std::cout (*p) ; // 先取 *p元素再自增 std::cout *p std::endl; return 0; }输出是1 2 3。逻辑拆开看*p等价于*(p)后缀自增优先级高于解引用先取值 1p 再移到 a[1](*p)先取值 2随后 a[1] 变成 3*p先把 p 移到 a[2]再取值 3。试卷换个包装就难倒一批人把cout换成printf把数组换成字符串本质还是同一套优先级问题。填空题的另一半命题点在sizeof与strlen、sizeof(a)与sizeof(p)。数组名作实参传入函数后就地退化为指针sizeof的语义随之改变这是“数组与指针联动”考法里最经典的一题。2.2 阅读程序写结果构造析构顺序和虚析构是拉开差距的题眼这类题不给编译机会只能手推最能暴露“凭感觉写代码”的问题。典型出题方式是把全局对象、局部对象、静态对象混在同一个程序里考构造与析构的先后。#include iostream class Demo { public: Demo(char c) : tag(c) { std::cout tag; } ~Demo() { std::cout static_castchar(tag 32); } private: char tag; }; Demo g(A); int main() { Demo d(B); static Demo s(C); return 0; }构造顺序是固定的程序装载期先构造全局对象 g输出 A进入 main 后按声明顺序构造局部对象 d 和静态对象 s输出 B、C。析构顺序与构造完全相反main 返回先析构局部对象 d输出 b静态对象 s 在 main 全部结束后析构输出 c全局对象 g 最后析构输出 a。完整输出是ABCbca。注意很多同学误以为静态对象和全局对象同时析构实际顺序是“局部先走、静态次之、全局殿后”同类内部按声明逆序。派生类参与时构造顺序是“基类→成员→自身”析构完全反转。这个考点通常和虚析构绑定出现。基类析构函数缺virtual时通过Base *p new Derived; delete p;只调用~Base()派生类析构被跳过。重载解析的考点则集中在匹配优先级实参类型精确匹配优先于标准转换标准转换优先于用户定义转换建议两处一起复习。2.3 手写代码题的题库范围冒泡排序、二分查找与判断质数的考场版本程序设计题不会超纲到 STL 全套但“排序、查找、数论入门”三件套出现概率极高。手写不需要奇技淫巧把边界条件写干净就是高分。void bubbleSort(int a[], int n) { for (int i 0; i n - 1; i) { bool swapped false; for (int j 0; j n - 1 - i; j) { if (a[j] a[j 1]) { int t a[j]; a[j] a[j 1]; a[j 1] t; swapped true; } } if (!swapped) break; } }三处细节对应三个扣分点内层上限n - 1 - i保证每轮冒泡后不再触碰已就位的最大值swapped标志让最好情况退化为 O(n)交换用临时变量手写避免部分判卷环境不认std::swap。很多教材不写提前退出加上反而体现对冒泡排序算法 C 版本复杂度的理解。二分查找的满分写法则盯着边界看int binarySearch(int a[], int n, int key) { int lo 0, hi n - 1; while (lo hi) { int mid lo (hi - lo) / 2; if (a[mid] key) return mid; if (a[mid] key) lo mid 1; else hi mid - 1; } return -1; }两个必记点mid lo (hi - lo) / 2避免lo hi溢出 int循环用lo hi区间真正空出来才退出能覆盖单元素数组和查找失败。把写成是最常见的手误走查数组[1]找1立刻露馅。判断质数的优化版本核心是“试到 √n并且跳过偶数”bool isPrime(int n) { if (n 2) return false; if (n 2) return true; if (n % 2 0) return false; for (int i 3; 1LL * i * i n; i 2) { if (n % i 0) return false; } return true; }1LL * i * i把乘法提升到 long long防止 i 接近 int 上限时溢出先排除 2 和偶数循环从 3 开始步进 2遍历次数减半。if (n 2) return false;是对 0 和 1 的兜底漏掉它判断题立刻翻车。提示手写代码题在函数开头注释里写明前置条件例如“a 已按非递减排序”阅卷时这部分计入完整性也帮自己稳住思路。3. 指针、数组与字符串C 期末卷里最容易翻车的三个连续考点指针在试卷里的存在感最强选择、填空、阅读程序、手写代码都会掺一脚。难的不是语法本身而是同一段代码在不同上下文里含义不同。复习时按声明、传参、返回三组对照来记效率最高。3.1 指针用法对照表4 种 const 组合与传参退化的记忆方法写法含义高频雷区const int *p;指向 const 的指针*p不可改误记成指针本身不可改int *const p;常量指针p 不可改误以为指向内容不可改int *p[3];指针数组3 个 int*与int (*p)[3]混淆int (*p)[3];指向含 3 个 int 数组的指针二维数组传参时才用记忆口诀const 在*左边锁住内容const 在*右边锁住指针本身。下面这段是最高频的辨析题素材int x 10, y 20; const int *p1 x; // 可改 p1不可改 *p1 p1 y; // 合法 // *p1 30; // 编译错误 int *const p2 x; // 可改 *p2不可改 p2 *p2 30; // 合法 // p2 y; // 编译错误传参退化是另一张必考面孔。void f(int a[], int n)、void f(int *a, int n)在函数签名层面是同一个东西数组形参就是指针形参所以长度 n 必须一并传入函数内部对a做sizeof得到的是指针大小。返回值的雷区更简单永远不要返回指向局部变量的指针局部变量随函数调用结束而销毁悬空指针是判断改错题的高频素材。3.2 字符串数组初始化的 4 种写法与 strlen 陷阱字符串考题集中在初始化写法和长度计算两处。同样存 hello四种写法结局完全不同char s1[] hello; // 6 字节末尾有 \0 char s2[6] hello; // 正好放下含 \0 char s3[] {h, e, l, l, o}; // 5 字节没有 \0 char *s4 hello; // 字符串字面量只读s1的strlen(s1)是 5sizeof(s1)是 6s3缺\0任何把它当 C 风格字符串输出的操作都会越界读到未知内存直到碰上一个 0 字节才停这是“看起来正常实则越界”的典型。s4指向只读区s4[0] H是未定义行为。字符串和数组互转是程序设计题的热门前置步骤。C 风格数组转std::string直接用构造函数反向拿可写缓冲区用strcpy#include cstring #include string char buf[64]; strcpy(buf, s1); // 数组 ← C 风格字符串目标要够大 std::string str(s1); // 数组 → std::string const char *p str.c_str(); // string → const char*只读视角c_str()返回的指针在 string 对象后续被修改后可能失效字符串转数组时最好先复制到本地缓冲区再用。这个细节在填空题里常被包装成“请写出不产生悬垂指针的写法”。3.3 用 vscode 配置 C/C 环境做离线刷题把“我以为”变成“编译器告诉我”复习指针和字符串最有效的方式是把选择题改写成小程序当场验证。本地装一套轻量 C/C 环境最实用Windows 装 MinGW-w64macOS 装 Xcode Command Line ToolsLinux 直接装 g。配合 vscode 的 C/C 扩展就有带智能提示的调试体验。g -stdc17 -Wall -Wextra -o main main.cpp ./main-Wall -Wextra打开常规警告定义未使用、符号比较、隐式转换这类考试代码里的常见毛病都会被点名-o main指定输出文件名保证编译通过才执行。验证字符串陷阱时一行printf(%zu %zu\n, strlen(s3), sizeof(s3));就能把书上的道理变成亲眼所见。如果 vscode 的智能提示和实际编译结果对不上多半是标准版本没对齐。在.vscode/c_cpp_properties.json里显式指定{ configurations: [ { name: exam-env, compilerPath: C:/mingw64/bin/g.exe, cppStandard: c17, intelliSenseMode: windows-gcc-x64 } ], version: 4 }compilerPath要与你实际装的编译器一致intelliSenseMode里的windows-gcc-x64对应 MinGW换成 MSVC 或 clang 都要改字段。这样刷题只需要 g 就能编译运行不必为平时练习安装整套 Microsoft Visual C 构建工具省掉一堆环境变量问题。4. 面向对象与流 I/OC 程序设计期末卷里分值最密的两块面向对象和流 I/O 是试卷后半部分的主场阅读程序题和文件读写题几乎都从这里出。这两块的特点是规则少而严背准规则就能稳定得分。4.1 继承体系下的构造析构顺序与虚析构的必要性写出下面程序的结果是这类题的标配#include iostream class Base { public: Base() { std::cout Base() ; } virtual ~Base() { std::cout ~Base() ; } }; class Derived : public Base { public: Derived() { std::cout Derived() ; } ~Derived() override { std::cout ~Derived() ; } }; int main() { Base *p new Derived; delete p; return 0; }输出是Base() Derived() ~Derived() ~Base()。构造时基类先执行派生类后执行析构时派生类先执行基类最后执行与构造严格逆序。真正的考点在virtual去掉它delete p按指针静态类型 Base 调用析构派生类析构函数根本不会执行。试卷常把这个改动包装成“程序输出是什么”或“存在什么隐患”。注意凡是可能通过基类指针删除派生类对象的类体系基类析构函数必须声明为 virtual否则属于未定义行为。4.2 重载、默认参数与 const 成员声明顺序决定能否编译默认参数只有一条规则从右往左连续给出。void f(int a, int b 1, int c 2);合法void f(int a, int b 1, int c);非法因为 c 没有默认值却排在带默认值的 b 之后调用时无法按位置对应实参。填空题经常把第二条包装成“指出编译错误并改正”。const 成员函数的重载是另一个高频点。同一个类写两个at靠对象的 const 性质区分class Str { public: char at(int i) { return buf[i]; } // 普通对象可读写 const char at(int i) const { return buf[i]; } // const 对象只读 private: char buf[128]; }; void printInfo(const Str s) { std::cout s.at(0); // const 对象 → 调用 const 版本 } Str s; s.at(0) A; // 普通对象 → 调用非 const 版本const 对象只能调用 const 成员函数非 const 对象优先匹配非 const 版本const 成员函数内部不能修改成员变量除非声明为mutable。这是一个接口、两种语义的惯用法在文本处理类程序设计题里几乎是标准答案。4.3 流 I/O 与文件读写的考场写法getline 循环代替 eof 判断文件读写题的套路稳定打开文件、逐行读取、处理、写回。最容易扣分的是循环终止条件。#include fstream #include iostream #include string int main() { std::ifstream fin(score.txt); if (!fin.is_open()) { std::cerr open failed std::endl; return 1; } std::string line; while (std::getline(fin, line)) { std::cout line std::endl; } fin.close(); std::ofstream fout(result.txt, std::ios::app); fout total 120 std::endl; fout.close(); return 0; }读取循环用std::getline的返回值判断读取是否成功不要先while (!fin.eof())再读——后者在读到文件末尾后还会多进一次循环体造成“多处理一行空数据”的经典错误。打开文件后立刻检查is_open()失败时打印错误并返回非零值这个习惯在改错题里也是加分项。std::ios::app表示追加写入std::ios::trunc表示打开即清空多个模式用|组合。常用模式对照如下模式效果应用场景std::ios::in只读打开ifstream 默认std::ios::out写入并清空ofstream 默认std::ios::app追加写日志、累加记录std::ios::ate打开后定位到末尾可读可写std::ios::binary二进制模式非文本文件统计文件里整数和这类任务配合std::istringstream逐行解析即可#include sstream int sum 0, v; std::istringstream iss(line); while (iss v) sum v;输出要保留固定小数位时用std::fixed std::setprecision(2)对应头文件iomanip。这两个小工具是流 I/O 题里最常见的临门一脚。5. 考前两周的“走查法”复习路线不依赖编译器也能抓出逻辑错误最后两周的复习重心不是增加新知识而是把已知内容练成条件反射。推荐“清单 走查”的组合白天按清单刷题晚上用走查法重演错题比盲目刷套卷更划算。5.1 把复习范围收敛成一张可勾选的清单模块必会内容自测标准语法运算符优先级、默认参数、重载匹配选择题不出错指针4 种 const 组合、数组退化、悬空指针能口头讲清差异面向对象构造析构顺序、虚析构、const 成员阅读题不丢分流 I/Ogetline 循环、打开模式、setprecision文件题一遍过清单只写“能默写”和“还不行”两栏第二天优先处理“还不行”那一格。程序设计实践类题目不必额外找新题把课堂例题换输入重跑就是最贴近考场的训练。5.2 手写代码的卷面规范阅卷视角的 3 个加分动作手写代码没有编译器提醒卷面即文档。第一函数开头用一行注释写明前置条件例如“数组 a 非空且按升序”第二变量名用可读形式i、j做循环下标可以t1、t2这类含义不明的缩写要避免第三边界条件单独成行处理if (n 0) return;放在函数入口第一行。这三个动作不改变算法正确性但能显著降低阅卷误判概率也帮你在检查时快速回忆思路。5.3 走查法用一张纸模拟编译器走查法是把“我以为是”改成“实际是”给定最小测试用例逐行记录变量值。以二分查找为例数组[1, 3, 5, 7]查找 5步lohimid动作10313 5lo 222325 命中返回 2再换一个不存在的 key6mid1 时 3 6lo 变 2mid2 时 5 6lo 变 3mid3 时 7 6hi 变 2此时 lo3 hi2循环退出返回 -1。三步走完边界条件的对错一目了然。提示拿到手写题先花两分钟写测试用例再动笔这个“先测后写”的顺序本身就是一次走查。考场上没有 GDB走查表就是你的调试器。把这张 lo、hi、mid 走查表直接画在演算纸空白处先填测试用例和变量列再动笔写代码就是一份不依赖编译器的调试循环。本文还有配套的精品资源点击获取