库函数memset及使用时的“陷阱”

这次介绍一个库函数memset的使用方法以及我对其的思考,请各位朋友耐心看完。

函数介绍

首先在使用之前,要包含一个头文件<string.h>,顾名思义,这是个与字符相关的库函数。

接下来就是其功能、参数、和返回值,如图:(翻译可能有些误差,英文好的老铁可以直接看第一张图)

这里我们就可以大致知道其功能就是:将指针指向的那块内存中的前num个字节的内容设置为我们想要的值

函数使用

在char类型的数组中,一个字符所占的空间为一个字节,那么就可以将其前num个字符改成指定的值。

 这里我们将指针ptr设为首元素地址arr,要设置的值value为'*',设置的字节数为5个字节,也就是5个字符的空间;可以看到,结果将"Hello"成功改为了"*****"。

这里我们突发奇想,能不能对整形数组使用memset呢?实践出真知,接下来就来举例,对一个整形数组int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }使用memset。

1.将其第一个元素的1设置为2。

因为整数在内存中是以二进制的形式存储的,int 型1 的二进制补码序列为000000000000000000000001,这里我们就可以把第一个字节中的1改为2,于是将指针ptr设为首元素地址arr,value设为2,num设为1。

这里可以看出成功了。

2.将其第一个元素设置为256。

这时我们要注意一个字节为8个比特位,最大能存储的值为11111111(二进制),也就是255,而256的无符号二进制序列为100000000,这时候我们发现超出一个字节空间的最大容量,预期修改的第一个元素的最终值的二进制序列为00000000000000000000000100000000,也就是256。

这里我们看到并没有像预期那样将1改成256。猜想原因在于value参数虽然是int类型的,但是在填充内存块之前要先转换为unsigned char 类型的值再进行填充,也就是先将256转换为unsigned char 类型,因为超出了最大值,所以会发生截断

 于是便把多出来的1丢了,所以其转换为unsigned char 类型的值为0,即用0填充,所以第一个元素的二进制序列为00000000000000000000000000000000,也就是0。

那么知道了这个条件以后,就能不能正确赋值了呢?

3.一个整形数组中的一个元素占四个字节的大小,我们就不像上面一样先研究其的二进制序列了,直接将空间大小设为4个字节,对它进行整体赋值。

 可是最终的结果却是这样,为什么呢,我们来内存中找答案。

 在VS编译器上,为了方便显示,采用16进制表示,但在内存中本质还是以二进制形式存储的(不了解整数在内存中存储的可以看我上一期的博客),红框中就是数组arr的空间,一行为一个元素的空间。调用memset后, 第一个元素的内存空间的值如图,

这里就引发了思考,为什么会这样,每个字节的内容都被改成了1,原来memset 是以字节为单位对内存进行设值的,也就是说,有n个字节的空间,memset 不是将这个空间作为整体进行赋值,而是以1个字节为单位,分别对n个空间进行赋值。

所以要对整形数组进行设值时,就只能设置0或者-1,因为它们转化成unsigned char 类型时的二进制序列分别为00000000、11111111,对每个字节分别赋值后的二进制序列分别为32个0,和32个1。正好就是0和-1。

最后,这里并不建议大家对非字符数组使用memset,如果使用不恰当,你就掉坑里去了。

好了,以上就是全部内容,感谢大家的阅读。

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值