关于memset赋值问题

时间:2021-10-19 17:17:14

学习借鉴自:https://blog.csdn.net/yexiaohhjk/article/details/52717934

memset是C语言头文件<string.h>中的一个函数,作用是在一段内存块中填充某个给定的值,它是对较大的结构体数组进行清零操作的一种最快方法

memset(数组名,赋值变量,数组长度);

void *memset(void *s, int ch, size_t n);

初始化清零是  memset(a,0,sizeof(a));
初始化无穷大是  memset(a,0x3f,sizeof(0x3f));

memset的赋值规则:

逐一对数组范围内的每个字节进行赋值(一字节 = 8_bit,1_bit = 一位二进制数)也就是也就赋值有效数值在8_bit(两位16进制);

假设我们对一个长度为2的int型数组进行赋值 0x3f4f5f6f(0x表示16进制,该数表示6进制数3F4F5F6F)memset(a,0x3f4f5f6f,sizeof(a))

在存储单元中就将得到 6F 6F 6F 6F    6F 6F 6F 6F

那么坑人的问题就出来了 a[0]=6F 6F 6F 6F ,而我们原来要的结果是把0x3f4f5f6f赋值给a数组;

当我们要用0x3f4f5f6f与a数组中的值对比时你就会发现不等于,那么我们的赋值就失去意义

现在我们用0x6f 赋值:

在存储单元中就将得到 6F 6F 6F 6F    6F 6F 6F 6F

#include<cstring>//C语言头文件在C++中的用法
#include<cstdio>
using namespace std;
int main(){
int a[];
printf("a数组字节数:\n%d\n",sizeof(a)); memset(a,0x6f,sizeof(a));
printf("给a数组赋值为0x6f:\n");
for(int i=;i<;i++)
printf("%d ",a[i]);
printf("\n"); memset(a,0x3f4f5f6f,sizeof(a));
printf("给a数组赋值为0x3f4f5f6f:\n");
for(int i=;i<;i++)
printf("%d ",a[i]);
printf("\n"); printf("赋值0x3f4f5f6f后的数组是否于0x3f4f5f6f相等:");
if(a[]==0x3f4f5f6f)
printf("yes");
else
printf("no");
return ;
}

当memset(,1,sizeof()); 1转为二进制0000 0001,当做一字节,一字节8位,int为4字节,所以初始化完每个数为0000 0001 0000 0001 0000 0001 0000 0001 = 16843009;

赋值无穷大问题:

这个问题是在我做最短路问题时,遇到的明明代码对了,却一直得不到想要的答案,最后对比别人的代码发现问题原来我的预设的无穷大值是0x3f3f3f;

那么就会出现上述的问题,数组值不等于我们赋的值。

赋值int型时,int型的位数根据编译器而定,现在一般主流的编辑器都是4字节,赋无穷大值时我们一般赋值所有 bit 位全 1 ,留一位当符号位,其余全1刚好是0x7fffffff

为什么无穷大值不取0x7fffffff,这个数是32_bit中最大的值,而取0x3f3f3f3f或0x3f(取0x3f时比较相等要和0x3f3f3f3f比),在编程过程中我们给一个数组赋值后是需要使用的,

如果你设置一个这么大的数的话,当进行加和操作的时候很容易数据溢出,而得到一个负数。所以这个数还需要能做的“无穷大加无穷大等于无穷大”,所以我们取0x3f3f3f3f或0x3f。

数值上0x3f3f3f3f是10^9,一般当无穷大已经够了,又满足“无穷大加无穷大等于无穷大”