这里我试图在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]);
}
}
答案 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的四个字节。