1007素数对猜想

题目:

题目要求找出 n(n<10^5) 中满足是素数且相邻两个素数的差值为 2 的素数对。

所以要先找出 n(n<10^5) 中的素数。定义函数判断出 n 中的素数。第一次写的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <math.h>
#define N 10000
int Judgement_primes(int n)
{ int i,flag=0;
if (n<=1) return flag;//如果n小于等于1,一定不是素数
else{
for (i=2;i<sqrt(n);i++) //判断i是不是素数
{
if (n%i==0) break;
else
{
flag=1;
}
}
}
return flag;
}

然后设计主函数,查找满足要求条件的素数对。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main(void)
{
int i,j=0,n,count=0,primes[N]={0};
scanf("%d\n”,&n);
for (i=2;i<sqrt(n);i++)//将是素数的值传递给数组premes
{
if (Judgement_primes(i)){primes[j++]==i;}
}
for (i=0;i<j;i++) //计算满足相邻素数差为2的素数对数
{
if (primes[i+1]-primes[i]==2){count++;}
}
printf("%d\n",count);
return 0;
}

太菜了,以为代码写出来就能跑了?交了好多遍啊,不是编译错误,就是段错误。

到底啥是段错误。

段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gd tr来保存的,他是一个48位的寄存器,其中的32位是保存由它指向的 gdt表,后13位保存 相应于gdt的下标,最后3位包括了程序是否在内存中以及程序的在cpu中的运行级别,指向 的gdt是由以64位为一个单位的表,在这张表中就保存着程序运行的代码段以及数据段的起 始地址以及与此相应的段限和页面交换还有程序运行级别还有内存粒度等等的信息。

​ –百度百科

简单来说就是访问了不可访问的内存,这个内存区要么是不存在的,

要么是受到系统保护的,还有可能是缺少文件或者文件损坏。

常见的段错误有以下的几类:

1
2
3
4
5
6
> int main(void)
> {
> char*s ="hello world";
> *s ='H';
> }
>

被装载时,系统把“hello world” 连同其它的字符串和const型数据放入到内存的只读区。执行时,一个变量s被设为指向该字符串的位置,当再试图向该位置写时,就会产生段错误。

1
2
3
> int*ptr = NULL;
> *ptr =1;
>

该代码只创建了一个空指针,并没有指向一个具体空间,当赋值时,产生段错误。

1
2
3
4
5
6
> int main(void)
> {
> main();
> return 0;
> }
>

无限递归,这会导致栈溢出,也会产生段错误。

​ –百度百科

在一次一次改了以后,终于找到影响段错误的地方:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int Judgement_primes(int n)
{ int i,flag=0;
if (n<=1) return flag;//如果n小于等于1,一定不是素数
else{
for (i=2;i<sqrt(n);i++) //判断i是不是素数
{
if (n%i==0) break;
else
{
flag=1;
}
}
}
return flag;
}

Judgement_primes 函数中 flag 先赋初值为 0,然后在后面代码中将其初值该为 1 。所以产生了上述的第一种常见段错误。

改为如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <stdio.h>
#include <math.h>
#define N 10000
int Judgement_primes(int n)
{ int i,flag;
if (n<=1) return flag=0;
else{
for (i=2;i<sqrt(n);i++)
{
if (n%i==0) break;
else
{
flag=1;
}
}
}
return flag;
}
int main(void)
{
int i,j,n,count,primes[N]={0};
scanf("%d\n",&n);
j=0;count=0;
for (i=2;i<sqrt(n);i++)
{
if (Judgement_primes(i)){primes[j++]==i;}
}
for (i=0;i<j;i++)
{
if (primes[i+1]-primes[i]==2){count++;}
}
printf("%d\n",count);
return 0;

}

改了以后,当然还是没有正确,太菜了。不过还好只是答案不对,继续改。

太菜了,一直改不对,参考了几个大佬的文章,还是改不对,就按着大佬的思路从新写了一遍。就不贴大佬的代码了,太打脸了。

一道题从九点写到十点多,都没 AC 。太菜了…….