前言:

今日份知识:memset函数!!!本周第三更!

话不多说,速速食用!


什么是memset函数?

memset,即memory set翻译过来就是内存设置。官方描述:memset函数是用来将指定内存设定为指定的字符。它的参数有三个,dest就是目标内存块(一定要输入地址),c是指定的内容,count是字节数。它的头文件是memory.h或者string.h


memset函数如何使用?

看实操:

上面是简单地对字符串使用memset函数。是为了让大家先简单了解一下memset如何使用

。下面将会说一些进阶知识。


memeset的进阶知识

例一:

在此程序中我们对于char,short,int类型的数组都设定内容为1,可是打印出来结果却不一样呢?

或许我们换个打印方式更清晰直观:

在此程序中我们用%x(即16进制,2个16进制位等于8个bit位等于一个字节)的形式打印,发现char类型的是1(即01),short类型的是101(即0101),int类型的是1010101(即01010101).这是因为char类型是一个字节,对其赋值的时候仅仅赋了一次01,short2个字节,int 4个字节。所以导致赋值后的内容不同。(对于类型大小,仅针对于32位编译器)

结论1:

在使用memset函数对内存进行赋值的时候要注意赋值对象的类型。

例二:

在此程序中我们将arr赋值为257,但是以16进制位打印出来结果却和例一中赋值1的结果一样。

解析:因为memset是一个字节一个字节赋值的,而一个字节能表示的大小只能是-128~127。257的2进制位是1 00000001,但赋值是只截取了1个字节即8比特位进行赋值,即00000001.所以结果和例一如出一辙。

结论2:

虽然指定内容类型为int,但是memset赋值时是按一个字节一个字节赋值的,所以赋值时只截取后8位bit位进行赋值。

例三:

既然例2中提及只截取后8位bit位进行赋值,那这8bit位表示的到底是无符号数还是有符号数呢?

看例子:

385的2进制序列是1 1000 0001,截取后8位即1000 0001。我们给a赋值385之后先以%x形式打印发现是81818181,而81转换是2进制位就是1000 0001,那么说明确实截取后8位了,a的二进制序列就应该是10000001 10000001 10000001 10000001 。

我们分别定义a为有符号整形和无符号整形。然后以%d,%u形式打印。

最终我们发现以%d打印就是-2122219135,以%u打印就是2172748161.

结论3:

这截取的8bit位是有符号还是无符号并不重要,重要的是赋值对象的类型和打印类型。因为最后的2进制序列都是一样的,就看如何解析还有如何定义了。

对象的类型决定内存中存储的内容大小。

打印的类型决定打印在屏幕上的大小。

如果不懂的可以去看我的unsigned详讲。

例四:

(因为我没有16位的编译器,所以先不放图片辣,感兴趣的可以去实践一下)

仔细看上面3个例子,每一次调用memset函数时,需要对整个对象进行赋值时,我都用的sizeof计算,原因有两点:1.因为sizeof返回类型是size_t,和memset函数中count的类型一样。

2.不同的编译器,类型的大小可能不一样。比如在16位编译器中int是2个字节,而32位编译器则是4个字节。

结论4:

在使用memset函数对于某个对象赋值时,尽量使用sizeof来传参

(当然特殊情况除外,比如需要修改字符串部分内容。)

例五:

在赋值为某个字符时:比如要赋值为b

1.可以写他的ASCII码值,也可以直接写其字符。

可以写98,也可以写'b',也可以'a'+1。

2.不可以写"b",因为""是用来引字符串的,memset不支持将内存块赋值为字符串。但是可以用memcpy函数。

3.也不可以写b,因为系统会默认b是一个未定义的变量,从而报错。


结语:

memset函数在对于初始化时非常方便,比for,while循环更快捷一些。但是memset也有局限性,它在对内存块赋值时,是一个一个字节赋值的。所以什么样的情况该使用怎样的方法需要多方面考虑!!!

到这里,本章就结束啦。如有错误,欢迎指正!!!

最后,还是坚定一下我的信念:

路漫漫其修远兮,吾将上下而求索!!!

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐