关于memset赋值问题
学习借鉴自:https://blog.csdn.net/yexiaohhjk/article/details/52717934
memset是C语言头文件<string.h>中的一个函数,作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法
memset(数组名,赋值变量,数组长度);
void *memset(void *s, int ch, size_t n);
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[2]; printf("a数组字节数:\n%d\n",sizeof(a)); memset(a,0x6f,sizeof(a)); printf("给a数组赋值为0x6f:\n"); for(int i=0;i<2;i++) printf("%d ",a[i]); printf("\n"); memset(a,0x3f4f5f6f,sizeof(a)); printf("给a数组赋值为0x3f4f5f6f:\n"); for(int i=0;i<2;i++) printf("%d ",a[i]); printf("\n"); printf("赋值0x3f4f5f6f后的数组是否于0x3f4f5f6f相等:"); if(a[0]==0x3f4f5f6f) printf("yes"); else printf("no"); return 0; }
当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,一般当无穷大已经够了,又满足“无穷大加无穷大等于无穷大”