c语言题目-素数

题目

在这里插入图片描述
输入一个数,程序打印出该数是否为素数

我的代码

#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;
	}

这样输出就正常啦~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值