/*利用筛选法求素数。输出(1,N]之间的所有素数。N由用户输入。*/
#include<stdio.h>
#include<stdlib.h>
int main()
{
unsigned int N=0;
unsigned int * numbers=NULL;
unsigned int i,j,flag=0;
printf("筛选法求素数,输出(1,N]的素数\n\n");
do{ //这个循环是用来保证正确输入N的值
printf("输入N的值:");
scanf("%u",&N);//%u保证输入的N不为负数
if(N<=1) //如果输入的N比2小,则提示重新输入
{
printf("N必须是大于1的正整数\n");
printf("请重新输入!或按Ctrl+C退出程序\n");
fflush(stdin);//把缓冲区清空,以便重新输入
}
}while(N<=1);//do...while循环结束。循环条件:N值小于2
fflush(stdin);//清空输入缓冲区
printf("N=%u\n\n",N);//打印用户输入的N值
numbers=(unsigned int *)calloc(N+1,sizeof(unsigned int));//分配内存并清零
if(numbers==NULL)//内存分配失败时,calloc返回值为NULL。程序出错退出
{
printf("内存分配失败!程序终止......\n");
exit(-1);
}
for(i=2;i<=N;i++)//i从2开始
{
flag=0; //打印标志,为0时表示本轮没有排除i的倍数
if(numbers[i]==0)//若前一次遍历未被排除
{
for(j=i+i;j<=N;j+=i)//能被2,3,5......等整除的一律排除置1
{
numbers[j]=1;//被排除的数j,对应数组元素值为1
printf(" %d ",j);//打印本轮被排除的数
flag=1;//打印标志,为1时表示本轮有i的倍数
}
if(flag==1)printf(" : %d 的倍数,被筛除\n",i);//打印本轮被排除的数
}
}
printf("\n------(1,%d]剩余素数列表--------\n",N);
for(i=2;i<=N;i++)//i从2开始
{ if(numbers[i]==0)printf(" %d ",i);//值为0的便是剩下的素数
}
putchar('\n');
free(numbers);//内存使用完后就要释放,通过指向该内存的指针变量来释放
return 0;
}