星期循环模运算
今天星期六,其后第N天星期几?如果是星期一到星期六输出形如:星期1、星期2等,星期天则输出星期天。下面的C++代码用于完成上述要求,横线处应填上的代码是()。
int N, remainder;
cin >> N;
remainder = ___;
if(remainder == 0)
printf("星期六后第%d天是星期天\n", N);
else
printf("星期六后第%d天是星期%d\n", N, remainder);
A.(
𝑁
+
6
)
/
7
(N+6)/7
B.(
𝑁
+
6
)
/
/
7
(N+6)//7
C.N % 7
D.(
𝑁
+
6
)
(N+6)
展开:答案、思考步骤与易错点
正确答案D
先这样想
先列变量每轮变化,再看输出语句是否真的执行。
分步推导
- 把星期六记作 6,向后走 N 天后可用 (N + 6) % 7 求结果。
- 若余数为 0,说明正好落在星期天;
- 其余余数 1 到 6 正好对应题目要求输出的“星期1”到“星期6”。
- 只写 N % 7 会把星期六当作起点 0,和题目映射不一致。
计算 / 追踪提示
计算时分清 `/` 是商,`%` 是余数;如果题目要求第 N 个位置,常要先改成从 0 开始的下标。
易错点
循环题不能只看“7 天一轮”,还要把起始星期六这个偏移量算进去。
双重循环输出
下面C++代码执行后的输出是()。
int i, j;
for(i = 0; i < 3; i++)
for(j = 0; j < i; j++)
printf("%d%d-", i, j);
printf("END");
A.0#0-1#0-2#0-2#1-END
B.0#0-1#0-1#1-2#0-2#1-2#2-3#0-3#1-3#2-END
C.0#0-1#0-1#1-2#0-2#1-2#2-END
D.1#0-2#0-2#1-END
展开:答案、思考步骤与易错点
正确答案D
先这样想
先列变量每轮变化,再看输出语句是否真的执行。
分步推导
- 当 i=0 时内层条件 j < i 不成立,没有输出。
- i=1 时输出一次 10-;
- i=2 时依次输出 20-、21-。
- 循环结束后再输出 END,所以完整结果是 10-20-21-END,对应选项 D 的写法。
计算 / 追踪提示
建议在草稿纸画三列:当前变量、条件真假、本轮输出。遇到 continue 直接跳到下一轮,遇到 break 只跳出当前循环。
易错点
外层从 0 开始,但 i=0 这一轮内层根本不会执行。
逻辑表达式整除判断
下面C++代码执行后,将输出不能被3整除且除以5余数为2的数。下列选项不能实现的是()。
int i, j;
for (i = 0; i < 100; i++)
if (____)
cout << i << endl;
A.(i % 3 != 0) && (i % 5 == 2)
B.(i % 3) && (i % 5 == 2)
C.(i % 3) && !(i % 5 != 2)
D.!(i % 3) && (i % 5 == 2)
展开:答案、思考步骤与易错点
正确答案D
先这样想
先确定除法的商和余数分别代表什么,再代入小样例检查。
分步推导
- 题目要求同时满足“不能被 3 整除”和“除以 5 余 2”。
- A 中 i % 3 != 0 正确表达了不能被 3 整除,B 中 i % 3 在 C++ 里非 0 即真,含义相同,C 里的 !(i % 5 != 2) 也等价于 i % 5 == 2。
- 只有 D 的 !(i % 3) 等价于 i % 3 == 0,反而筛出能被 3 整除的数。
计算 / 追踪提示
建议在草稿纸画三列:当前变量、条件真假、本轮输出。遇到 continue 直接跳到下一轮,遇到 break 只跳出当前循环。
易错点
!(i % 3) 表示“余数为 0”,不是“不能被 3 整除”。
自守数判断循环变量更新
判断一个数是否为自守数。自守数的定义是如果一个数的平方其尾数与该数相同,则为自守数,如 25 的平方是 625,其尾数是 25,所以 25 是自守数。相关说法错误的是()。int N, N1, M1;
cout << "输入一个正整数:";
cin >> N;
N1 = N, M1 = N * N;
bool Flag = true;
while (N1 > 0){
if (N1 % 10 != M1 % 10){
Flag = false;
break;
}
else{
N1 = N1 / 10, M1 = M1 / 10;
}
}
if (Flag == true){
printf("%d的平方是%d,是自守数", N, N * N);
else{
printf("%d的平方是%d,不是自守数", N, N * N);
}
}
A.如果Flag在循环中不被改为false,则说明该数是自守数
B.代码 if (N1 % 10 != M1 % 10) 用于判断其个位数是否相等,如果不等,则表明不是自守数
C.代码 N1 = N1 / 10, M1 = M1 / 10 将个位数去掉
D.将 N1 > 0 改为 N > 0 效果相同
展开:答案、思考步骤与易错点
正确答案D
先这样想
先列变量每轮变化,再看输出语句是否真的执行。
分步推导
- 程序通过比较 N 与 N*N 的末位是否逐位相同来判断自守数,所以 B、C 的说法都对;
- 如果每一位都匹配,Flag 不会被改成 false,A 也正确。
- D 错在把 while (N1 > 0) 改成 while (N > 0) 后,循环体里并没有更新 N,条件始终不变,程序逻辑就被破坏了。
计算 / 追踪提示
建议在草稿纸画三列:当前变量、条件真假、本轮输出。遇到 continue 直接跳到下一轮,遇到 break 只跳出当前循环。
易错点
循环条件里应使用会被不断缩小的变量,而不是原始输入值。
变量作用域循环中的状态延续
下面 C++ 代码实现输出如下图形。关于该程序的说法,错误的是( )。程序运行示例:
请输入行数: 10
0
12
345
6789
01234
567890
1234567
89012345
678901234
5678901234
代码如下:
#include <iostream>
using namespace std;
int main() {
int line_number, now_number;
int i, row;
cout << "请输入行数: ";
cin >> line_number;
now_number = 0;
for (row = 1; row < line_number + 1; row++) { // L1
for (i = 0; i < row; i++) { // L2
cout << now_number;
now_number += 1;
if (now_number == 10) now_number = 0; // L3
}
cout << endl;
}
return 0;
}
A.代码 now_number = 0 移动到 L1 和 L2 标记的两行代码之间,效果维持不变
B.代码 now_number += 1 修改为 now_number = 1 + now_number 效果维持不变
C.将代码 now_number == 10 调整为 now_number > 9 效果维持不变
D.将最后一行的 cout << endl 修改为 cout << "\n",效果维持不变
展开:答案、思考步骤与易错点
正确答案A
先这样想
先列变量每轮变化,再看输出语句是否真的执行。
分步推导
- now_number 在外层循环开始前只初始化一次,所以数字会在各行之间连续接着输出。
- 若把 now_number = 0 挪到 L1 和 L2 之间,它会在每一行开始时重置为 0,每行都会从 0 开始,输出明显改变,因此 A 错。
- B 只是交换加法写法,C 把 ==10 改成 >9 等价,D 中 endl 与 "\n" 都能换行。
计算 / 追踪提示
建议在草稿纸画三列:当前变量、条件真假、本轮输出。遇到 continue 直接跳到下一轮,遇到 break 只跳出当前循环。
易错点
这题关键不在语法,而在变量是否跨行保留上一次的状态。
比较运算逗号运算符
下列C++代码执行后,其输出为 10 20 ,即 a == b 和 b == a 对 a 和 b 的值没有任何影响。()
int a = 10, b = 20;
a == b;
b == a;
cout << (a, b);
判断本题结论:先独立判断,再展开答案。正确答案是 错误。
展开:答案、思考步骤与易错点
正确答案错误
先这样想
把题干拆成两半:事实是否正确,结论是否被事实支持。
分步推导
- a == b 和 b == a 的确都只是比较,不会改动变量值;
- 但最后输出的是 cout << (a, b);,逗号表达式的值等于最后一个操作数 b,所以只会输出 20,不是题干说的 10 20。
- 因此整句话是错误的。
计算 / 追踪提示
输出题不要只算值,还要看格式控制、空格、换行和输出语句的位置。
易错点
判断题要看整句,前半句对不代表后半句也对。
最大值与最小值相等判断
a 和 b 分别是 C++ 的整型变量,如果表达式
max
(
𝑎
,
𝑏
)
=
=
min
(
𝑎
,
𝑏
)
max(a,b)==min(a,b)的值为真,则说明 a 和 b 相等。()
判断本题结论:先独立判断,再展开答案。正确答案是 正确。
展开:答案、思考步骤与易错点
正确答案正确
先这样想
把题干拆成两半:事实是否正确,结论是否被事实支持。
分步推导
- 若 max(a, b) == min(a, b),说明较大的那个值和较小的那个值相同,只可能是 a 与 b 相等。
- 只要两个数不相等,最大值一定大于最小值,表达式就不可能为真。
计算 / 追踪提示
讲评时可以先让学生口头说出排除理由,再打开解析核对。
易错点
不要把 max、min 当成“可能接近”即可,它们相等只能发生在两数完全相等时。
循环边界求和范围
将下面C++代码中的(int i = 5; i > 1; i--)调整为(int i = 1; i < 5; i++) 输出结果相同,因为5到1与1到5的求和相同。()int tnt;
tnt = 0;
for (int i = 5; i > 1; i--)
tnt += i;
cout << tnt;
cout << endl;
判断本题结论:先独立判断,再展开答案。正确答案是 错误。
展开:答案、思考步骤与易错点
正确答案错误
先这样想
先列变量每轮变化,再看输出语句是否真的执行。
分步推导
- 原循环累加的是 5 + 4 + 3 + 2 = 14,因为条件是 i > 1,不会加到 1。
- 改成 for (int i = 1; i < 5; i++) 后累加的是 1 + 2 + 3 + 4 = 10。
- 虽然两个式子都像是在“1 到 5 之间求和”,但边界不同,结果并不相同。
计算 / 追踪提示
建议在草稿纸画三列:当前变量、条件真假、本轮输出。遇到 continue 直接跳到下一轮,遇到 break 只跳出当前循环。
易错点
比较两段循环时,要把起点、终点和是否取到边界都写清楚。
二维图形输出奇偶列定位
为实现如下效果,即N行N列字符。当输入是奇数时,中间列为*,其他是-;当输入是偶数时,则中间两列是*,其他是-。字符阵阵列后的代码能实现其效果。()
/*
5
--*--
--*--
--*--
--*--
*/
int N;
cin >> N;
int i,j;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++)
if ((j == N / 2) || (j == (N-1) / 2))
cout << "*";
else
cout << "-";
cout << endl;
}
}
判断本题结论:先独立判断,再展开答案。正确答案是 正确。
展开:答案、思考步骤与易错点
正确答案正确
先这样想
把题干拆成两半:事实是否正确,结论是否被事实支持。
分步推导
- 当 N 为奇数时,N / 2 与 (N - 1) / 2 相同,只会有一列满足条件,所以中间列输出 *。
- 当 N 为偶数时,这两个值分别对应中间偏右和中间偏左两列,因此会输出两列 *。
- 外层循环控制行数,内层循环控制每行的列数,题目描述与代码效果一致。
计算 / 追踪提示
建议在草稿纸画三列:当前变量、条件真假、本轮输出。遇到 continue 直接跳到下一轮,遇到 break 只跳出当前循环。
易错点
整数除法会向下取整,偶数和奇数时这两个中间位置的结果不同。