memset()函数对数组初始化

memset函数在初始化数组时,通常用于赋值为0或-1,因为这些值的二进制形式在所有字节中都相同。赋值其他值可能导致错误,如将整型数组初始化为100时,实际值会变成1684300900。正确使用memset需要考虑赋值的二进制表示,并且在某些情况下可以使用特定值如0x3f3f3f3f来表示无穷大。

前言

我们在做算法题是常常会用memset函数对一个数组初始化,一般初始化为1或0时没有问题,即
memset(a, 0, sizeof a);但是在赋值为其他值时会莫名其妙地出现错误的数字。

memset函数原形

void *memset(void *str, int c, size_t n)
  • 功能:复制一个无符号字符 c 到参数 str 所指向的字符串的前 n 个字符。是对较大的结构体或数组进行清零操作的一种最快方法
  • 使用前需要引入头文件,C中#include<string.h>,C++中#include<cstring>

使用时的注意事项

在使用时我们需要提醒自己memset赋值是按字节赋值, 即将参数化成二进制之后填入一个字节

  • 例1: 想要通过memset(a,100,sizeof a)int类型的数组赋值,目标值为100,转成二进制就是0110 0100 (注意只有最后一个字节有效),而int有四个字节,也就是说,一个int被赋值为0110 0100,0110 0100,0110 0100,0110 0100,对应的十进制是1684300900,根本不是我们想要100
A[0]A[1]
0110 0100,0110 0100,0110 0100,0110 01000110 0100,0110 0100,0110 0100,0110 0100
0xFFFFFFFF0xFFFFFFFF
16843009001684300900
  • 例2:memset(a,-1,sizeof a)同样给int类型的数组赋值,这次我们的目标值为 -1,转换成 2 进制为全 1 ,只有最后一个字节有效,也就是 1111 1111,int有四个字节,每个字节被 1111 1111 填充,变为1111 1111,1111 1111,1111 1111,1111 1111 也就是 -1 的补码,对应的十进制就是 -1 ,和我们最初的目标是一样的。
  • 例3:如果目标值为 0 , 对应的二进制为全 0 ,最后一个字节自然也是全 0 ,填充到int型变量的四个字节中后自然也算是全 0 ,对应的十进制也是 0 ,这就解释了为什么我们用memset函数将 int 型 数组初始化为 -1 或 0 时没问题,换成其他数字就会出错

结论

  • str指向char型地址,value可为任意字符值;
  • str指向非char型,如int型地址,要想赋值正确,value的值不可以随便取,一般只能是 -1 或 0 ,因为 -1 和 0 转化成二进制后每一位都是一样的,设int型占4个字节,则-1=0XFFFFFFFF, 0=0X00000000。

扩展

memset初始化为无穷大:

memset(a , 0x3f , sizeof a);

如设置一个无穷大常量为0x7fffffff,这个数是32位int型的最大值,符号位为0,其他的都是1。但是这个值在相加时会溢出,这样两个无穷大数相加会变成负数。

为了尽量避免以上的错误,我们可以将0x3f3f3f3f设为无穷大,这个数已达到10^9,足以表示无穷大,又因为0x3f3f3f3f+0x3f3f3f3f=2122219134,满足无穷大+无穷大仍为无穷大。当把无穷大设为0x3f3f3f3f时,在做初始化时也很方便。

如在初始化数组a时,可以使用memset(a,0x3f,sizeof(a)),因为0x3f3f3f3f的每个字节都是0x3f,如果使用0x7fffffff,需要循环赋值。

无穷小则用 0xc0c0c0c0 来表示, 理由与无穷大同理,也是为了避免在跑数据时溢出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值