MIDPOINT / FIRST ATTEMPT
M1:把已经学过的东西,独立组合起来。
先完成基础01–09的全部内容,再开始这次检查。你将保存五份预测、自己的小程序、三份找错说明和一次口述。这里不提供程序实现或追问答案。
首轮安排90分钟,满分100分。它已经包含在154核心小时路线内,不另加90分钟。这个时间尚未经过真人校准;实际超时、使用提示或后续复测都如实另记,不挤掉第09章的视图与失效学习。
开始前,保留一份自己的记录
准备一个新的文件夹,把本次预测和说明写在自己的文本文件中,把程序写在自己的.cpp文件中。不要覆盖之前的练习。记下日期、尝试编号、开始时间,以及是否已经看过这份题的评分或实现。
可以使用已配置好的编辑器、编译器和终端,也可以阅读诊断并自己修正。独立阶段不查看本题答案,不用代理生成的实现代写。诊断出来后自行修正仍属于独立调试;看过参考后完成则记为练习,之后用等价新题复核。
本页不会创建进度记录或判定通过。保存自己的原文件即可;阅读评分、截图、收藏和跑通教师示例都不能自动通过M1或G0。
| 时间 | 任务 | 分值 |
|---|---|---|
| 0–15分钟 | 闭卷预测五题,先写结果与原因 | 25 |
| 15–50分钟 | 从空文件独立写程序、编译与测试 | 45 |
| 50–65分钟 | 静态找错三题,不执行非法访问 | 20 |
| 65–80分钟 | 解释本人代码,接收一个窄迁移追问 | 10 |
| 80–90分钟 | 对照评分,决定补练与复测 | 不计分 |
通过需要同时满足:总分至少80、预测至少20/25、程序至少36/45、五个指定输入均实际通过,以及四项关键概念全对。完整判断还包括程序合同、独立性和口述,保存初答后再对照评分标准。
0–15分钟:先预测,不运行(25分)
前四题是完整程序,每题各自独立。每题5分:结果或状态2分,原因和过程3分。保留初答;之后发现错了,在旁边记录修正,不擦掉最初判断。
1 · 表达式与接收类型
写出标准输出。再分别写出除法两侧操作数的类型、除法结果的类型,以及保存到result时发生了什么。不要先运行。
#include <iostream>
int main() {
int total{7};
int batches{3};
double result = total / batches;
std::cout << result << '\n';
return 0;
}2 · 循环执行了几次
分别为n=0、n=1列出:result初值、第一次条件判断、循环体执行次数、更新次数、返回值。最后写出main的标准输出。
#include <iostream>
int accumulate(int n) {
int result{0};
for (int i{0}; i < n; ++i) {
result += 2;
}
return result;
}
int main() {
int first{accumulate(0)};
int second{accumulate(1)};
std::cout << first << ' ' << second << '\n';
return 0;
}3 · 调用之后的两个对象
写出标准输出,并说明original、形参value和result各自经历了什么。指出哪一个对象被value += 3修改。
#include <iostream>
int adjusted(int value) {
value += 3;
return value;
}
int main() {
int original{4};
int result{adjusted(original)};
std::cout << original << ' ' << result << '\n';
return 0;
}4 · 两次赋值之后
在r = b和b = 9之后各画一行a、b、r的状态,再写出最终标准输出。用一句话解释r与对象的关系。
#include <iostream>
int main() {
int a{4};
int b{7};
int& r{a};
r = b;
b = 9;
std::cout << a << ' ' << b << ' ' << r << '\n';
return 0;
}5 · 作用域之后(5分)
下面只是在main内观察的片段,已包含iostream。判断最后一行是否有可以合法承诺的确定输出;如果不能,指出相关对象的生命周期结束点,并说明“指针不是空值”是否足以支持这次读取。
仅作纸面分析,不编译、不执行这段片段,也不尝试用一次运行结果猜答案。
// 只作静态分析:这是 main 内的片段,不是可运行示例。不要执行末行。
int* p{nullptr};
{
int local{4};
p = &local;
}
std::cout << *p << '\n';15–50分钟:独立写BatchSummary(45分)
定义一个BatchSummary类。构造函数只接收一段std::span<const int>,在构造过程中计算元素数量和总和。对象只保存这两个独立的标量结果,提供const查询;不要保存span、裸指针或引用成员,也不要让外部任意改写统计状态。
输入在整个构造过程中有效。最多10项,每项在0–100内,因此总和最多1000;计数可以用已授的std::size_t,总和使用int。本题只要求处理合同内输入,不要求解析命令行、读取用户输入或增加泛化溢出机制。
在main内创建已初始化的容器作为输入。可以使用普通下标循环或范围for,不用算法库、lambda、智能指针、异常、模板定义或继承。查询函数名称可以自选,评分看行为与对象关系,不要求代码与某份参考逐字一致。
五个固定输入,全部实际核对
| 输入 | count | total |
|---|---|---|
[] | 0 | 0 |
[5] | 1 | 5 |
[2,0,3] | 3 | 5 |
[0,0] | 2 | 0 |
[100,100] | 2 | 200 |
每组同时核对数量和总和。程序应从传入的数据计算,不能识别这五组输入再返回预写结果。只保存统计值这一点也是任务合同;五行输出碰巧正确,不代表对象关系正确。
保留一次真实构建过程
下面沿用已学过的严格编译命令。文件名可改成自己的实际文件名;修改源码后要重新编译,再运行刚生成的产物。
clang++ -std=c++20 -Wall -Wextra -Wpedantic -Werror batch-summary.cpp -o batch-summary && ./batch-summary保存本人源码、实际命令、终端退出状态和五组结果。保留一条实际诊断及自己的修复;如果没有遇到错误,就明确写“这次没有出现编译错误”,不编造一次调试经历。编译操作忘记时可回看已有编译教程,并记录使用了这项参考。
50–65分钟:找出第一处合同问题(20分)
三段代码都只作静态分析,没有运行下载入口。写清失效或非法访问发生的位置、原因和修法;不要给未定义行为指定“正确输出”。
1 · 准备容量之后(7分)
这是main内的片段,已包含vector和iostream头文件。指出第一次非法访问在哪里;在那之前分别写出size与容量满足什么条件,并给一个最小的合法修法。
// 只作静态分析:这是 main 内的片段,不是可运行示例。不要执行末行。
std::vector<int> values;
values.reserve(3);
std::cout << values[0] << '\n';2 · 返回一段数据(7分)
这是一个函数定义,已包含vector与span头文件。调用者准备接收返回值并读取第0项。指出哪一个对象在哪一步结束、返回值是否还可用于读取,并给出一种截至第09章能说明清楚的接口修法。
// 只作静态分析:不要用返回视图访问元素;这里没有可运行的 main。
std::span<const int> borrowed_values() {
std::vector<int> local{2, 4, 6};
return std::span<const int>{local};
}3 · 追加后的旧名字(6分)
本题明确给定:push_back正常完成,且这一次确实发生重分配。指出从哪一步开始不能再用旧引用读取;说明应怎样重新获得所需元素。不要猜某个实现的增长倍数或实际地址。
// 只作静态分析:这是 main 内的片段,不要执行末行。
// 题目给定:下面的 push_back 已正常完成,而且这一次确实发生重分配。
std::vector<int> values{2, 4};
int& first{values[0]};
values.push_back(6);
std::cout << first << '\n';65分钟:先保存,再开始口述
先保存预测、找错初答和本人源码。用自己的程序解释:输入容器是谁的,构造时哪些对象参与计算,统计对象之后还需要哪些对象存活。可以录一小段语音或写逐句记录。
请评审者在首次源码提交后,从评分页领取窄迁移追问。自学时也先保存上述口述,再打开评分页;先回答追问题面并保存,最后展开对照。提前看过追问答案,就不能再把它记为陌生迁移,应换一道等价题。
这个链接只是导航,不检查文件是否存在,也不记录验收结果。M1未通过时,按具体缺口补练再复测;通过M1仍不等于通过最终G0。