素数探求小学生计算机辅助系统( prime Number computer)
程序目的:熟悉函数设计,循环控制的方法以及程序测试的方法,了解什么是边界测试,体会模块化程序设计和函数复用的好处和意义
总结:
模块设计使得工作量大大减少,使得不用关心函数具体咋样实现。使得在进行功能的变更时(ps:这个懂了写没啥动力)
我们依旧把题目放在前面(ps:第一次用markdown不习惯)
任务一
题目
试商法是最简单的判断素数方法。用I = 2~m-1之间的整数去试商。若存在某个m能被1和m 本身以外的整数i所整除,则m不是素数,若上述范围内的所有整数都不能不能整除。采用试商法,分别用go to语句,break 语句,和采用设置标志变量并加强测试循环等3中种方法编写素数判断函数Isprime(),从键盘任意输入一个整数m,判断m是否为素数,如果 m是素数那么按"%d is aprime Number\n"格式打印该数是素数吗,否则按“%d is not prime number"的格式打印该数不是素数,分析哪种方法的可读性更好。
代码
(1)使用goto语句
//任务一
//使用goto语句
#include <stdio.h>
int Isprime(int x);
int main()
{
int m;
printf("Input m");
scanf("d", &m);
if (Isprime(m)) /*素数判断*/
printf("%d is a prime number\n", m);
else
printf("%d is not prime\n", m);
return 0;
}
int Isprime(int x)
{
int i;
if (x <= 1)
return 0;//负数,0,1都不是素数
for (i = 2; i < x - 1; i++)
{
if (x % i == 0)
goto End;//若不能被整除,则不是素数
}
End:
return i <= x - 1 ? 0 : 1;
}
int Isprime(int x)
{
int i;
if(x<=1) return 0;//负数,0,1都不是素数
for(i=2;i<x-1;i++)
{
if (x%i == 0) goto End;//若不能被整除,则不是素数
}
End return i<=x-1?0:1;//三目运算符
}
(2)break语句编写
//任务一
//break语句编写
#include <stdio.h>
int Isprime(int x);
int main()
{
int m;
printf("Input m");
scanf("d", &m);
if (Isprime(m)) /*素数判断*/
printf("%d is a prime number\n", m);
else
printf("%d is not prime\n", m);
return 0;
}
int Isprime (int x)//判断是否为素数
{
int i;
for (x <= 2; i <= x - 1 ; i++)
{
if (x % i == 0)
break;
}
return i < x - 1 ? 0 : 1;
}
(3)利用设置标识符和加强测试循环
//任务一
//利用设置标识符和加强测试循环
#include <stdio.h>
int Isprime(int x);
int main()
{
int m;
printf("Input m");
scanf("d", &m);
if (Isprime(m)) /*素数判断*/
printf("%d is a prime number\n", m);
else
printf("%d is not prime\n", m);
return 0;
}
int Isprime(int x)//判断是否为素数
{
int i, flag = 1;//flag为标识符
if (x <= 1 )
return 0;
for ( i = 2; i <= x - 1 ; i++)
{
if (x % i == 0)
flag = 0;
}
return flag;
}
思考:
goto语句,能够帮助跳出循环,尤其是多层循环,能减少标识符的使用,但容易造成逻辑混乱使代码的可读性变差,应该尽量向下跳跃,避免程序出错的可能
任务二
题目:用数学方法可以证明,不能被2~ m \sqrt{m} m,(取整数)之间的数整除的数也不能被 m \sqrt{m} m+1 ~ m
之间的任何整数整除。因此采用试商法只要测验2~ m \sqrt{m} m能不能整除m即可判断m是素数。根据这个性质,修改函数Isprime(),编程完成任务一。
代码:
//任务二
#include <stdio.h>
#include <math.h>
int Isprime(int x);
int main()
{
int m;
printf("Input m:");
scanf("%d",&m);
if(Isprime(m))/*素数判定*/
printf("%d is not a prime number\n",m);
else
printf("%d is not a prime number \n",m);
return 0;
}
int Isprime(int x)
{
int i, flag = 1;
int squareRoot = (int)sqrt(x);
if (x < 1)
flag = 0;/*负数,0和1都不是素数*/
for (i = 2; i <= squareRoot && flag; i++)
{
if (x % i == 0)
flag = 0;
}
return flag;
}
任务三
题目
任务三:从键盘任意输入一个整数n,编程计算并输出 1~n之间的所有素数之和
思路
循环用for循环控制流程,用sum 记录和
代码
//任务三
#include <stdio.h>
#include <math.h>
int Isprime(int x);
int main()
{
int m, n, sum = 0;
printf("Input n: \n");
scanf("%d", &n);
for (m = 1; m <= n; m++)
{
if (Isprime(m)) /*素数判定*/
{
sum += m;
}
printf("sum = %d\n", sum);
return 0;
}
}
/*函数功能:判断x是否是素数,若函数返回0,则表示不是素数;若返回1,则表示是素数*/
int Isprime(int x)
{
int i, flag = 1;
int squareRoot = (int)sqrt(x);
if (x < 1)
flag = 0;/*负数,0和1都不是素数*/
for (i = 2; i <= squareRoot && flag; i++)
{
if (x % i == 0)
flag = 0;
}
return flag;
}
任务四
题目
任务四:从键盘任意输入一个整数m,若m不是素数,则计算并输出其所有因子(不包括1),例如对于16,输出2,4,8,否则输出“No divisor!It is aprime number".
思路
代码
//任务4
#include <stdio.h>
#include <math.h>
int Isprime(int x);
int main()
{
int m, i, isFirstFactor = 1;
printf("Input m:");
scanf("%d", &m);
if (Isprime(m)) /*素数判定*/
{
printf("No divisor!It is a prime number\n");
}
else
{
for (i = 2; i < fabs(m); i++)
{
if (m % i == 0)
{
if (isFirstFactor == 0)
printf(",");
printf("%d", i);
isFirstFactor = 0;
}
}
printf("\n");
}
return 0;
}
/*函数功能:判断x是否素数,若函数返回0,则表示不是素数,若返回1,则表示是素数*/
int Isprime(int x)
{
int i, flag = 1;
int squareRoot = (int)sqrt(x);
if (x < 1)
flag = 0;/*负数,0和1都不是素数*/
for (i = 2; i <= squareRoot && flag; i++)
{
if (x % i == 0) flag = 0;
}
return flag;
}
任务五
题目
任务五:如果一个正整数m所有小于m的不同因子(包括1)加起来正好等于m本身,那么就称它为完全数(perfect Number)。例如,6是一个完全数 ,因此6=1+2+3。试编写一个判断完全数的函数Isperfect(),然后判断从键盘输入的整数是否是完全数。
思路
代码
#include <stdio.h>
#include <math.h>
int Isperfect(int x);
int main()
{
int m;
printf("Input m:");
scanf("%d", &m);
if (Isperfect(m))
printf("%d is not a perfect number\n", m);
else
printf("%d is not a perfect number \n", m);
return 0;
}
int Isperfect(int x)
{
int i;
int total = 0; /*1没有真因子,不是完全数*/
for (i = 1; i < x; i++)
{
if (x % i == 0)
total = total + i;
}
return total == x ? 1 : 0;
}
任务六
题目
任务六:从键盘任意输入一个整数m,若m不是素数,则对m进行质因数分解,并将m表示为质数从小到大顺序排列的乘积形式输出,否则输出"It is a prime number"例如,用户输入90时,程序输出90=23#*5;用户输入13时,程序输出" It is a prime number"
代码
#include<stdio.h>
#include<stdlib>
#include<time.h>
int isprime(int x);
void OutputPrimeFactor(int x);
int main()
{
int m;
printf("Input m:");
if(Isprime(m))/*素数判定*/
{
printf("It is aprime number\n");
}
else
{
printf("%d=",m);
outputPrimeFactor(M);/*输出x的质因连乘*/
}
return 0;
}
/*函数功能:哦判断 x是否为素数,若函数返回0,则表示不是素数,若返回1,则表示是素数*/
int Isprime(int x)
{
int i,flag=1;
int squareRoot = (int)sqrt(x);
if(x<=1) flag =0;
for(i = 2;i<= squareRoot&&flag;i++)
{
if(x%i == 0) flag = 0;
}
return flag;
}
void OutputPrimeFactor(int x)
{
int i;
for(i = 2;i<x;i++)
{
if(x%i == 0)
{
printf("%d*",i);
OutputprimeFactor(x/i);/*递归调用该函数*/
}
}
}
总结:边界条件是当if语句不执行的时候,你发现递归调用虽然简单明了,但会造成重复计算,可能造成溢出。