#include <stdio.h>
#include <stdlib.h>
//布尔类型头文件
#include <stdbool.h>
void fun(int *arr,int size){
//遍历数组
for(int i=0;i<size+1;i++){
//假设刚开始是质数
bool is_prime=true;
if(arr[i]<2){
//除去0,1的情况
continue;
}
//判断是否为质数
for(int j=2;j<arr[i];j++){
if(arr[i]%j==0){
//不是质数,直接跳出循环
is_prime=false;
break;
}
}
if(is_prime) {
printf("%d是质数\t",arr[i]);
}
}
}
int main(){
int a=0,b=0;
printf("请输入你要求质数的区间:\n");
//判断scanf合法性
if(scanf("%d %d",&a,&b)!=2){
printf("输入不合法,请输入数字!");
return 1;
}
//判断区间合法性
if(a>b){
int t=a;
a=b;
b=t;
}
//计算数组元素个数
int n=b-a+1;
//初始为空,防止垃圾值
int *numbers=NULL;
//动态申请数组空间
numbers=(int*)malloc(n*sizeof(int));
//判断是否分配成功
if(numbers==NULL){
printf("分配内存失败!");
return 1;
}
//填入数组
for(int i=0;i<n;i++){
numbers[i]=a;
a++;
}
fun(numbers,n);
//释放空间
free(numbers);
numbers=NULL;
return 0;
}
如何判断一个数是否为质数?一个数是否为质数就看除它本身和1之外还有没有数能够整除。例如3,除了1和它本身(3)没有其他能整除。
利用这个思想,我们可以设计一个函数fun()传递数组参数之后,逐步判断上述的添加,用布尔类型标记出来,满足条件的是质数,不满足的淘汰。
下面是部分运行结果:
请输入你要求质数的区间:
1 50
2是质数 3是质数 5是质数 7是质数 11是质数 13是质数 17是质数 19是质数 23是质数 29是质数31是质数 37是质数 41是质数 43是质数 47是质数
请按任意键继续. . .
可以看到,如果区间过大的话,输出结果太复杂和繁琐,那我们可不可以优化一下,定义一个数组,将所有是质数的数填进去,最后输出数组?
下面来优化一下:
#include <stdio.h>
//动态分配头文件
#include <stdlib.h>
//布尔类型头文件
#include <stdbool.h>
//传递双指针,待会返回主函数用
int fun(int **arr,int *size){
int prime=0;
//定义一个新的临时数组
int *temp=NULL;
//初定义数组长度
int temp_space=*size;
//分配空间
temp=(int*)malloc(temp_space*sizeof(int));
if(temp==NULL){
printf("分配内存失败!");
return 1;
}
//遍历数组
for(int i=0;i<*size;i++){
//假设刚开始是质数
bool is_prime=true;
if((*arr)[i]<2){
//除去0,1的情况
continue;
}
//判断是否为质数
for(int j=2;j<(*arr)[i];j++){
if((*arr)[i]%j==0){
//不是质数,直接跳出循环
is_prime=false;
break;
}
}
//填写新的数组元素
if(is_prime) {
temp[prime]=(*arr)[i];
prime++;
}
}
//释放原来的指针数组
free(*arr);
//重新分配新的数组长度
int *new_temp=(int*)realloc(temp,prime*sizeof(int));
if(new_temp==NULL){
// 重新分配失败,释放临时数组内存并返回错误码
printf("重新分配内存失败!");
//释放空间,提前结束进程
free(temp);
return 1;
}
//封装进原数组地址,传递给主函数
*arr=new_temp;
*size=prime;
return 0;
}
int main(){
int a=0,b=0;
printf("请输入你要求质数的区间:\n");
//判断scanf合法性
if(scanf("%d %d",&a,&b)!=2){
printf("输入不合法,请输入数字!");
return 1;
}
//判断区间合法性
if(a>b){
int t=a;
a=b;
b=t;
}
//计算数组元素个数
int n=b-a+1;
//初始为空,防止垃圾值
int *numbers=NULL;
//动态申请数组空间
numbers=(int*)malloc(n*sizeof(int));
//判断是否分配成功
if(numbers==NULL){
printf("分配内存失败!");
return 1;
}
//填入数组
for(int i=0;i<n;i++){
numbers[i]=a;
a++;
}
int x=fun(&numbers,&n);
if(x==0){
printf("这些数是质数\n");
for(int j=0;j<n;j++){
printf("%d\t",numbers[j]);
}
//释放空间
free(numbers);
numbers=NULL;
return 0;
}else{
free(numbers);
numbers=NULL;
return 1;
}
}
使用双地址很有难度,也非常考验代码水平,双地址的主要作用是函数fun中的数据再次传递出来给主函数,其实和普通地址用法差不多,主要是要注意不要少写*号了。
另外,对于提前不知道长度的临时数组temp,我们用了realloc函数,实现二次分配空间。
最重要的就是参数n了,用地址来使它成为全局变量,不管数组怎么变,它还是最终的数组长度。
下面是部分运行代码:
1 100
这些数是质数
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
请按任意键继续. . .
注:该代码是本人自己所写,可能不够好,不够简便,欢迎大家指出我的不足之处。如果遇见看不懂的地方,可以在评论区打出来,进行讨论,或者联系我。如果可以,可以点一个免费的赞支持一下吗?谢谢各位彦祖亦菲!!!!!