内存函数:如何使用与模拟实现

张开发
2026/4/19 0:53:44 15 分钟阅读

分享文章

内存函数:如何使用与模拟实现
专栏C语言文章目录一.memcpy ----- 内存块拷贝1.1函数原型包含功能参数返回值1.2举例1.3memcpy的模拟实现二.memmove ----- 内存块拷贝⬅️可处理重叠2.1函数原型包含功能参数返回值2.2举例2.3memmove的模拟实现三.memset ----- 内存块按字节设置3.1函数原型包含功能参数返回值3.2举例四.memcmp ----- 内存块逐字节比较4.1函数原型包含功能参数返回值4.2举例总结⚠️易错点这次我会根据标准C库函数参考对 memcpy、memmove、memset、memcmp 四个内存操作函数进行标准定义、参数说明、举例以及各自函数的模拟实现。前言在C语言编程中字符串函数仅能处理以\0结尾的字符数据适用场景有限。而内存操作函数直接以字节为单位对任意类型数据进行拷贝、移动、赋值与比较不依赖数据类型、不受结束符限制是编写通用、高效、底层代码的核心工具。本篇将学习memcpy、memmove、memset、memcmp四大内存函数从用法、原理到手写模拟实现全覆盖帮助大家真正掌握内存层面的数据操作逻辑提升代码的健壮性与编程能力。一.memcpy ----- 内存块拷贝1.1函数原型包含功能参数返回值函数原型void*memcpy(void*destination,constvoid*source,size_tnum);功能从source指向的内存向后复制 num 个字节destination指向的内存不关心数据类型只做二进制级别的逐字节拷贝如果两块内存存在重叠时复制结果为未定义行为头文件string.h参数destination目标内存起始地址source源内存起始地址num要复制的字节数返回值返回目标内存destination的起始地址。1.2举例#includestdio.h#includestring.hintmain(){intarr1[]{1,2,3,4,5,6,7,8,9,10};intarr2[10]{0};memcpy(arr2,arr1,20);inti0;for(i0;i10;i){printf(%d ,arr2[i]);}return0;}分析先定义两个整型数组arr1 为源数据arr2 为目标空间然后调用memcpy拷贝20字节相当于5个int最后循环打印 arr2 内容。运行结果1.3memcpy的模拟实现#includeassert.hvoid*my_memcpy(void*dst,constvoid*src,size_tcount){void*retdst;assert(dst!NULL);assert(src!NULL);while(count--){*(char*)dst*(char*)src;dst(char*)dst1;src(char*)src1;}returnret;}分析用 assert 断言保证指针非空再强转为 char* 实现逐字节拷贝保证通用性接着循环 count 次完成指定字节数拷贝最后返回复制后目标空间地址。二.memmove ----- 内存块拷贝⬅️可处理重叠2.1函数原型包含功能参数返回值函数原型void*memmove(void*destination,constvoid*source,size_tnum);功能功能与memcpy一致但可以安全处理内存重叠。无论源、目标内存是否重叠都能正确复制。头文件string.h参数destination目标内存起始地址source源内存起始地址num要复制的字节数返回值返回目标内存destination的起始地址。2.2举例#includestdio.h#includestring.hintmain(){intarr1[]{1,2,3,4,5,6,7,8,9,10};memmove(arr12,arr1,20);inti0;for(i0;i10;i){printf(%d ,arr1[i]);}return0;}分析先在同一个数组内进行拷贝存在内存重叠再使用 memmove 保证数据不被破坏最后打印数组观察重叠拷贝结果。运行结果2.3memmove的模拟实现#includeassert.hvoid*my_memmove(void*dst,constvoid*src,size_tcount){void*retdst;//保存目标地址assert(dst!NULL);assert(src!NULL);//情况1不重叠从前往后拷贝if(dstsrc||(char*)dst(char*)srccount){while(count--){*(char*)dst*(char*)src;dst(char*)dst1;src(char*)src1;}}//情况2重叠从后往前拷贝else{//跳到最后一个字节开始拷贝dst(char*)dstcount-1;src(char*)srccount-1;while(count--){*(char*)dst*(char*)src;dst(char*)dst-1;src(char*)src-1;}}returnret;}分析首先判断地址关系选择拷贝方向当发现重叠时从后往前拷贝避免覆盖源数据因为是逐字节操作兼容所有类型。三.memset ----- 内存块按字节设置3.1函数原型包含功能参数返回值函数原型void*memset(void*ptr,intvalue,size_tnum);功能将ptr指向的内存按字节设置为value。共设置num个字节。头文件string.h参数ptr要设置的内存起始地址value要设置的值只取低 8 位按字节设置num要设置的字节数返回值返回ptr指向的内存起始地址3.2举例#includestdio.h#includestring.hintmain(){charstr[]hello world;memset(str,x,6);printf(%s\n,str);return0;}分析先对字符串前 6 字节批量赋值为 ‘x’然后按字节修改速度快适合初始化。运行结果四.memcmp ----- 内存块逐字节比较4.1函数原型包含功能参数返回值函数原型intmemcmp(constvoid*ptr1,constvoid*ptr2,size_tnum);功能比较ptr1和ptr2指向的内存块逐字节比较前num个字节不关心数据类型只比较二进制值。头文件string.h参数ptr1待比较内存块 1ptr2待比较内存块 2num要比较的字节数返回值当0时ptr1 ptr2当0时ptr1 ptr2当0时ptr1 ptr24.2举例#includestdio.h#includestring.hintmain(){charbuffer1[]DWgaOtP12df0;charbuffer2[]DWGAOTP12DF0;intnmemcmp(buffer1,buffer2,sizeof(buffer1));if(n0)printf(%s 大于 %s\n,buffer1,buffer2);elseif(n0)printf(%s 小于 %s\n,buffer1,buffer2);elseprintf(%s 与 %s 相同\n,buffer1,buffer2);return0;}分析先逐字节比较两块内存区域然后根据返回值判断大小关系。运行结果总结1.memcpy通用内存拷贝以字节为单位复制数据不支持内存重叠但效率较高。2.memmovepro版本内存拷贝支持内存重叠工程中更安全。3.memset以字节为单位初始化内存常用于内存置 0、置字符。4.memcmp以字节为单位比较两块内存不受\0结束符限制可比较任意数据。5. 四个函数均依赖头文件string.h以void*为参数支持任意数据类型操作⚠️易错点memcpy处理重叠内存导致数据被覆盖、结果异常。memset按字节赋值误用给int数组设为1结果并非每个元素为1。拷贝/比较时字节数num计算错误造成内存越界。模拟实现时未将void*强转为char*无法正确逐字节操作。忘记使用assert(断言)校验指针合法性传入空指针导致程序崩溃。混淆memcmp与strcmpmemcmp不遇到\0停止会严格比较num个字节。遗漏头文件string.h导致函数未定义报错。 关注 一路同行从入门到大师慢慢沉淀、稳步成长❤️ 点赞 鼓励原创让优质内容被更多人看见⭐ 收藏 收好核心知识点与实战技巧需要时随时查阅 评论 分享你的疑问或踩坑经历一起交流避坑、共同进步

更多文章