哥德巴赫猜想是指大于 $2$ 的偶数都可以分解为两个质数之和,下面的代码用于验证 $4\sim 1000$ 之内的偶数能否分解为两个质数之和。下面 C++ 代码中假设 isPrime() 是已经定义好用于判断正整数 $N$ 是否为质数,返回 bool 值。对该段代码,错误的说法是( )。
for (i = 4; i < 1000; i += 2)
for (j = 2; j < i; j++)
if (isPrime(j) && isPrime(i-j)){
printf("%d=%d+%d\n", i, j, i-j);
break;
}答案D。for循环每次迭代后执行更新表达式(如i++)。循环体执行次数由初始值、条件和更新共同决定。
循环变量的初值、终值和步长共同决定循环次数。for(i=0;i<n;i++)执行n次。
【考点】循环结构|逻辑表达式
1. 考纲定位:GESP二级 算法模块3.2"循环与条件判断",出题人专挑"循环终止条件"与"if块作用域"的混淆点,卡住考生对break语句执行范围的理解。
2. 解题思维:外层循环枚举偶数i,内层循环从小到大枚举j,一旦发现isPrime(j) && isPrime(i-j)成立就输出并break——因此输出的j必然是满足条件的最小质数,i-j必然大于j。
3. 陷阱拆解:A项:isPrime返回bool,&&两边直接写函数调用即可,加==true纯属多余但逻辑等价,A正确。B项:j从2开始递增,i-j随之递减,break后输出的j一定是当前i对应的较小质数,B正确。C项:枚举范围再扩大也只是验证更多数据,不能构成数学证明,C正确。D项:break在if块内,只在找到分解时跳出内层循环;若移到if外,无论是否找到分解都会立即break,导致无法输出或跳过后续j,D错误。
4. 反命题思维:若把break移到循环外,则每次内层循环只执行一次判断,永远找不到第二个质数,程序输出将变成空行;若把isPrime(j) && isPrime(i-j)改成isPrime(j) || isPrime(i-j),则会输出大量无效等式。刷到此类题先问自己"循环何时真正终止"。