今天在对欧拉筛这个算法练习的时候,发现了一直没有对memset的初始化的误区,在对一个欧拉筛的板子的代码找bug,却一直找不出来。
原始错误代码
#include<stdio.h>
#include<string.h>
int a[1000005];
int prin[1000000];
void prinme()//素数打表
{
memset(a,1,sizeof(a));//将数组全部初始化为1
a[0]=0,a[1]=0;
int t=0;
for(int i=2;i<=1000000;i++)
{
if(a[i])
prin[t++]=i;
for(int j=0;j<t&&prin[j]*i<=1000000;j++)
{
a[prin[j]*i]=0;
if(i%prin[j]==0)
break;
}
}
}
int main()
{
int n;
int i;
int cnt=0;
scanf("%d",&n);
prinme();
for(i=0;i<=n;i++)
{
if(a[i]==1)
cnt++;
}
printf("%d\n",cnt);
return 0;
}
发现错误
按道理来说输出的值应该为4,但这里却是0,所以将数组a[0]–a[8]的值一一打出来,如图:
在这里发现,memset()对数组a的初始化没有起作用,然后将数组a全部初始化为1,来对这个代码进行反向修改,得到了正确答案。
正确代码:
#include<stdio.h>
#include<string.h>
int a[1000005];
int prin[1000000];
void prinme()
{
memset(a,0,sizeof(a));
a[0]=1,a[1]=1;
int t=0;
for(int i=2;i<=1000000;i++)
{
if(!a[i])
prin[t++]=i;
for(int j=0;j<t&&prin[j]*i<=1000000;j++)
{
a[prin[j]*i]=1;
if(i%prin[j]==0)
break;
}
}
}
int main()
{
int n;
int i;
int cnt=0;
scanf("%d",&n);
prinme();
for(i=0;i<=n;i++)
{
if(a[i]==0)
cnt++;
}
printf("%d\n",cnt);
return 0;
}
这样方可得到正确答案。
memset
memset是计算机中C/C++语言初始化函数。作用是将某一块内存中的内容全部设置为指定的值, 这个函数通常为新申请的内存做初始化工作。
memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法
memset不能将整数数组初始化为0,-1之外的其他值
memset函数按字节对内存块进行初始化,所以不能用它将int数组初始化为0和-1之外的其他值(除非该值高字节和低字节相同)。
这是对memset()函数的一个误区的发现过程,推荐可看看下面这篇博客——更多的关于memset函数;
点击这进入,了解更多关于memset
或者点击下面链接:
https://blog.csdn.net/wang907553141/article/details/52080495
第一篇博客,有错误请指出。谢谢!