前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >字节序列操作函数

字节序列操作函数

作者头像
phith0n
发布2020-10-15 22:21:44
5970
发布2020-10-15 22:21:44
举报
文章被收录于专栏:离别歌 - 信息安全与代码审计

字节序列操作函数

字符串是以\0(即NUL)结尾的一串字符指针。所以一个字符串内部不可能包括任何NUL字符,但是,非字符串数据内部包含NUL的并不罕见。我们不能用字符串函数(如strcat/strcpy等)来处理这些数据,因为他们碰到NUL就会停止工作。

不过"mem"家族的函数给了我们几大帮助,它们能处理任意的字节序列,是对内存的直接操作。

memcpy

函数原型:void *memcpy(void *dest, const void *src, size_t n);

这个函数长的就和strcpy很像,就是姓不同,估计是表兄吧。作用是从src指向的地址开始,复制n个字节的数据到dest指向的地址里。其中n是size_t类型,很多同学表示不懂,其实size_t就是无符号整型。

取n的时候一定要注意,不要以为char就一定是一个字节,于是字符串有5个字母就填5.一定要用sizeof取一下你要复制的数据所占的内存大小。

与strcpy的区别在于,memcpy函数能够处理非字符串的数据,比如memcpy(value1,value2,sizeof(value2));其中value2可以是int 类型的数组,而value1可以是int 类型的指针。他们并不需要强制转换成void 类型的指针,因为任何类型指针都可以直接转换成void* 类型。

注意,当dest 和 src 指向的地址在内存里发生重叠了,会产生不可预料的后果。(于是,下面一个函数应运而生)

memmove

函数原型:void *memmove( void* dest, const void* src, size_t count );

这个函数和上一个用法一样,但它的源和目标可以重叠。就好像操作是这样:先把src保存的内容复制到一个临时的地址保存,再将这个内容从临时地址拷贝到dest中。这样即使dest和src指向的地址重叠,也能完成拷贝操作(只是效率低了)。所以,如果地址真的可能发生重叠的时候,务必就要用上memmove函数了,比如:

代码语言:javascript
复制
memmove(arr+1,arr,10*sizeof(arr[0])); //将arr数组整体向后移动一个位置

memcmp

函数原型:void* memcmp(const void* a,const void* b,size_t length);

用法与strcmp相似,从ab指向的地址开始,对无符号字符逐字节进行比较,共比较length个字节。相等返回0,a小于b返回负值,a大于b返回正值。如果a、b地址里保存的不是字符类型,就会产生不可预料的错误。

memchr

函数原型:void* memchr(const void* a,int ch,size_t length);

从a的起始位置开始查找ch第一次出现的位子,并返回一个指向该位置的指针。它共查找length个字节。如果未找到则返回NULL.

memset

函数原型:void* memset(void* a,int ch,size_t length);

这个放在最后,其实用的反而比较多,把从a开始的length个字节都初始化为ch.

大概常用的就是这些。有了这些函数,我们就扩展了许多对于数组进行操作的知识。而且我们还要注意,不要总想着自己写一个函数来替代库函数的功能。这些库函数用汇编写的效率已经是很高了,我们把它们记住,需要的时候就直接用。

C的魅力我就不多说了,这些对于系统内存操作的函数已经将她展现的淋漓尽致。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 字节序列操作函数
    • memcpy
      • memmove
        • memcmp
          • memchr
            • memset
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档