题目
输入一个数,程序打印出该数是否为素数
我的代码
#include<stdio.h>
#include<math.h>
//输入一个数,判断它是不是素数
int main(){
int n,i=1;
printf("请输入一个数(0和1非素数):");
scanf("%d",&n);
for(i = 2;i<=sqrt(n);i++){
if(n%i==0){
break; //如果有能整除的数,就证明不是素数,所以要break出来
}
}
printf("%d",i);
if(i<=sqrt(n)){ //这里要区分开是break出来的,还是正常跳出循环的
printf("你输入的%d不是素数",n);
}else{
printf("你输入的%d是素数",n);//如果依然满足条件,那就说明是因为break出来的,因为break也是在满足条件的情况下跳出来,如果是正常跳出来的话肯定是不满足for循环条件跳出来
}
return 0;
}
代码2
#include <stdio.h>
#include <math.h>
int main()
{
int n, tmp;
int i;
printf("input n(>3):");
scanf("%d", &n);
i = 2;
tmp = sqrt(n);
while( i <= tmp) {
if (n % i == 0)
break;
i++;
}//这里是用while实现的
if (i <= tmp)
printf("%d not\n", n);
else
printf("%d yes\n", n);
return 0;
}
经验
1、break理解错误,我以为它只是在不符合条件的那一次循环跳出去,其实它是直接终止了整个离它最近的循环,比如虽然只有第五次循环不符合条件,但break了以后,第5次以及以后的循环都不执行了。
2、数学上有一个规定是,如果要判断一个数是否为素数,在除以一个数的时候,只用除到√n,因为:
当我们尝试将一个数 n 分解为两个因子 a 和 b 时,我们需要满足以下条件:
a * b = n
a <= b
假设我们找到一个因子 a,如果 a > sqrt(n),那么根据条件2,b = n / a 必定小于或等于 sqrt(n)。这是因为 a * b = n,而 a > sqrt(n),所以 b = n / a 小于 n / sqrt(n) = sqrt(n)。换句话说,如果 a 超过了 sqrt(n),那么对应的 b 也会小于或等于 sqrt(n)。
因此,如果在判断一个数 n 是否为素数时,我们遍历的范围是 2 到 sqrt(n)。如果在范围内找到了一个能整除 n 的因子 a,那么根据上述推理,对应的 b = n / a 将会小于或等于 sqrt(n)。这意味着我们不需要再继续搜索大于 sqrt(n) 的范围。如果不存在范围内的因子 a,我们可以确定不存在对应的 b,即 n 是素数。
因此,判断一个数是否为素数时,我们只需要遍历 2 到 sqrt(n) 的范围,而不需要继续搜索大于 sqrt(n) 的范围。这样可以有效地减少循环次数,提高程序的效率。
3、最后代码注释部分
完善程序
现在确实是可以判断用户输入正确的数据是否为素数,但是有时候难免用户会手滑输入错误,比如这时候如果用户输入了一个字符,那么我们希望程序能够报错,并让用户重新输入,这里用到了两个知识点:1、n = scanf(“%d”,&a),这里n是scanf的返回值,如果只输入成功了一个变量,那么就返回1,这里输入的类型给定的是整数,如果你输入的是字符的话,那么返回值就是0。
2、如果是这样的代码(仅提供一部分):
#include<stdio.h>
#include<math.h>
//输入一个数,判断它是不是素数
int main(){
int n,i;
loop: //通过goto来实现在用户输入错误后让用户重新输入并判断
printf("请输入一个数(0和1非素数):");
if(scanf("%d",&n)==0){
printf("输入错误");
goto loop;
}
那么会输出以下结果:
就是无限循环输出,这里是犯了一个严重的错误:当我们输入了一个w字符后,由于scanf内的类型并不是%c,所以变量n根本不会拿到这个w值,所以它就一直存放在输入缓冲区中,输入缓冲区一直是满的状态,所以再次遇到goto到一开始scanf的位置返回值仍然为0,由此才不断循环。所以我们要把代码修改一下,在输入w这样的字符后,用另外一个函数把这个w拿走,吸收掉:
#include<stdio.h>
#include<math.h>
//输入一个数,判断它是不是素数
int main(){
int n,i;
loop:
printf("请输入一个数(0和1非素数):");
if(scanf("%d",&n)==0){
printf("输入错误");
getchar(); //补充getchar()
goto loop;
}
这样输出就正常啦~