素数的判断是C语言初学者一道经典的题目,小编总结了解题的思路和一写常见的坑,供大家参考~(考察知识点:循环语句、条件判断语句以及它们的嵌套、break、continue等)
1.题目描述:用户输入一个数字,写一个程序判断该数字是不是素数。(素数:除了1和本身以外没有其它的因数的数,比如3、5、7等)
2.大体思路:
1.设输入的数字为a,那么我们需要判断a%(2~a)==0是否成立,涉及到多次重复的取余操作,因此我们需要写入循环。
2.当循环执行的过程中发现a%i==0成立(2<i<a),那么说明a除了1和本身以外还有其它的因数,即该数不是素数,后面的除数就无需判断了,此时程序退出(break)循环即可。(退出循环后,此时2<i<a)
3.当i从2到a全部遍历一遍后,a%i==0仍然不成立,那么说明a是素数。(退出循环后,此时i=a+1)
4.打印判断结果:根据推出循环后i的值来进行区分,从而打印出结果。
3.代码初步实现
#include<stdio.h>
int main()
{
int a;
printf("请输入你要判断的数:");
scanf("%d",&a);
int i=2;#因为循环体外要使用变量i,所以这里的i定义在外边。
for(;i<=a;i++){
if(a%i==0)
break;
}
if(i<=a)
printf("%d不是素数。\n",a);
else
printf("%d是素数。\n",a);
}
return 0;
}
4.代码优化
1.i无需从1判断到a,判断到根号a即可。(数学原理自行bing~)
2.当用户输入非数字字符或者小于2的数字时,应提示用户重新输入。
5.优化实现
1.引入数学函数库,在循环跳出判断的时候把a换成根号a即可。
2.当用户输入非法数据时,程序应提示用户,之后返回到程序开头,让其重新输入。因此我们需要写一个具有“折返”功能的循环,例如goto或者while(True)+continue,这里我们以后者为例进行探讨。伪代码实现如下:
#include<stdio.h>
#include<math.h>
int main()
{
int a;
while(1){
printf("请输入你要判断的数:");
if(scanf("%d",&a)==0||a<2){
printf("请输入大于2的整数!\n");
continue;
}
int i=2;
for(;i<=sqrt(a);i++){
if(a%i==0)
break;
}
if(i<=sqrt(a))
printf("%d不是素数。\n",a);
else
printf("%d是素数。\n",a);
}
return 0;
}
但是我们在调试的过程中,输入一个字符时,发现程序会陷入死循环,这是为什么呢?因为if里的“scanf("%d",&a)==0"是成立的,函数可以从缓冲区(程序和用户链接的枢纽)接收到字符,但是这个字符会一直存储到缓冲区,函数会一直读取,条件会一直成立,所以会陷入死循环。为了解决这个问题,我们可以引入”getchar()”函数,它是C语言中的一个标准库函数,功能是从缓冲区读取一个字符,并将其返回。简单来说就是用这个函数把缓冲区输入的字符给“吃掉”,进而使scanf无法读取到字符,解决死循环的问题。
至此,程序大体上已经OK啦,但是还有最后一个小问题,就是如何退出程序。我们可以默认规定一下,当用户输入“#”时,程序将结束循环,退出程序。
最终代码如下:
#include<stdio.h>
#include<math.h>
int main()
{
int a;
while(1){
printf("请输入你要判断的数(按#结束判断):");
if(scanf("%d",&a)==0||a<2){
if(getchar()=='#')
break;
else{
printf("请输入大于2的整数!\n");
continue;
}
}
int i=2;
for(;i<=sqrt(a);i++){
if(a%i==0)
break;
}
if(i<=sqrt(a))
printf("%d不是素数。\n",a);
else
printf("%d是素数。\n",a);
}
return 0;
}
此外,值得一提的是,变量i既不能定义在for循环括号里面,也不能和a一起定义在全局变量的位置,因为定义在里面下面的判断语句无法使用;定义在上面,当我们进行多轮判断时,i的初值会停留在上一轮的赋值,会影响我们的判断。
好了,以上就是对判断素数问题的全部介绍。小编写的可能有遗漏或者错误,恳请各位评论区指正~
另外小编正在学习嵌入式Linux软件开发、langchain—LLM应用开发,会一直更新学习笔记,对以上以及C++、Python、数据结构与算法等领域感兴趣的小伙伴可以关注我,我们一起进步!