为什么第一个素数总是变为1而不是2

时间:2016-10-22 09:21:18

标签: c sieve-of-eratosthenes

这里我试图在c中实现erastosthene筛。除了一个主要问题外,程序工作正常。我手动设置第一个素数值为2.但是当我循环遍历所有素数数组时并打印出来,第一个值变为1而不是2.可以弄清楚为什么会出现这个问题。非常感谢任何帮助。

#include<stdio.h>
#include<math.h>
int main(){

    int n = 64;
    int i,j,limit=sqrt(n)+2,nPrime=0;
    int prime[50]={0},mark[64]={0};
    mark[1]=1;

    prime[nPrime++] = 2;
    printf("%d\n",prime[0]); // initialized to 2



    for(i=4;i<=n;i=i+2){
       mark[i] = 1;
    }
    for(i=3;i<=n;i=i+2){
       if(!mark[i]){
           prime[nPrime++] = i;
           if(i<=limit){
              for(j=i*i;j<=n;j=j+i*2){
                 mark[j]=1;
              }
           }
       }
    }
    int k;
    int size = sizeof(prime)/sizeof(prime[0]);
    printf("%d\n",prime[0]);  // changed to 1;
    for(k=0;k<size && prime[k]!=0;k++){
        printf("%d ",prime[k]);
    }

}

2 个答案:

答案 0 :(得分:1)

问题出现在这个循环中:

for(i=4;i<=n;i=i+2) {
    mark[i] = 1;
}

条件应该是i < n,因为使用<=它将取值64,这将超出范围。

当您设置mark[64] = 1时,您正在修改不属于标记数组的内存,在这种情况下,它将成为素数组的第一个元素。如果您测试其他索引,最终可能会出现段错误。

如果您手动设置mark[64] = 56,则会看到prime[0] == 56

答案 1 :(得分:0)

因为局部变量是在堆栈上声明的,所以在你的情况下,变量mark [64]是64个整数(64 * 4 = 256个字节)的数组占用堆栈的前256个字节然后是数组素数(50 * 4 = 200字节)占用接下来的200个字节,如下所示:

                           Stack
                       |-----------|
                       |   other   |
                       | variables |
                       |           |
            prime[49]->|-----------| addr = 0x000001C8
                       |           |
                       |   prime   |
                       |(200 bytes)|
             prime[0]->|           |
             mark[63]->|-----------| addr = 0x00000100 
                       |           |
                       |           |
                       |   mark    |
                       |(256 bytes)| 
                       |           |
              mark[0]->|-----------| addr = 0x00000000

当你写mark [64] = 1时,你实际上正在写入prime [0] = 1的四个字节。