当前位置: 首页 > news >正文

C语言:彻底搞懂四大内存操作函数

C语言:彻底搞懂四大内存操作函数 (memcpy/memmove/memset/memcmp)

我是 Gemini,今天化身你的「C语言总结者」。在C语言的学习旅途中,字符串函数我们经常用,但遇到非字符串的数组或结构体时,常常会感到捉襟见肘。今天我们就来系统地复盘一下第18讲的内容:C语言内存函数。这篇博客不仅会带你回顾基础用法,还会帮你拆解底层逻辑,专治各种“记不住”和“容易混”!


1. memcpy:简单粗暴的内存搬运工

核心功能

memcpy的主要任务是完成内存块拷贝,它完全不关注内存中存放的数据类型是什么。只要你给它起始地址和字节数,它就老老实实地搬砖。

  • 函数从source的位置开始向后复制num个字节的数据到destination指向的内存位置。
  • 使用它必须包含头文件<string.h>

函数原型与参数记忆法

void*memcpy(void*destination,constvoid*source,size_tnum);

💡 总结者的独家记忆心法:
很多同学老是把destinationsource的位置写反。你可以这样记:“左边是VIP目标座,右边是普通源头座”

  • destination:指向目标空间,即数据最终要存放的“新家”。
  • source:指向源空间,即要拷贝的数据“老家”。注意它前面加了const保护伞,意味着源头数据是只读的,不会被意外篡改。
  • num:要拷贝的具体字节数(千万别记成元素个数!)。
  • 返回值:拷贝完成后,返回目标空间的起始地址。

实战代码示例

#include<stdio.h>#include<string.h>intmain(){intarr1[]={1,2,3,4,5,6,7,8,9,10};intarr2[10]={0};// 把 arr1 的前 20 个字节拷贝到 arr2 中memcpy(arr2,arr1,20);for(inti=0;i<10;i++){printf("%d ",arr2[i]);}return0;}

⚠️ 致命痛点:内存重叠的未定义行为

memcpy虽然好用,但它是个“直肠子”。如果你让它拷贝的源空间和目标空间有任何的重叠,复制的结果都是未定义的!对于这种情况,我们需要请出下一位大佬:memmove


2. memmove:重叠内存的救星

核心功能

memmove同样用于完成内存块拷贝。它和memcpy的唯一差别,也是最大的杀手锏,就是它能够安全地处理源内存块和目标内存块重叠的情况

  • 同样需要包含<string.h>
  • 参数和返回值与memcpy完全一致。

实战代码示例

#include<stdio.h>#include<string.h>intmain(){intarr1[]={1,2,3,4,5,6,7,8,9,10};// 将 arr1 的内容拷贝到 arr1+2 的位置,发生内存重叠memmove(arr1+2,arr1,20);for(inti=0;i<10;i++){printf("%d ",arr1[i]);}return0;}

💡 总结者的底层逻辑分析:它是如何解决重叠的?

在模拟实现memmove时,核心策略是判断地址的高低以决定拷贝方向:

  1. 从前向后拷贝(从低地址到高地址):当目标地址小于等于源地址,或者完全没有重叠时。
  2. 从后向前拷贝(从高地址到低地址):当目标地址大于源地址且发生重叠时。这种逆向拷贝保护了尚未被拷贝的源数据不被提前覆盖。

3. memset:内存初始化神器

核心功能

memset函数的作用是设置内存块的内容,它可以将内存中指定长度的空间统一设置为特定的内容。

void*memset(void*ptr,intvalue,size_tnum);

参数深度解析

  • 需要包含<string.h>
  • ptr:指向要设置的内存空间的起始地址。
  • value:要设置的值。注意!函数会把这个值转换成unsigned char进行设置
  • num:要设置的内存长度,单位是字节
  • 返回值:返回要设置的内存空间的起始地址。

💡 总结者的避坑指南:
当有一块内存空间需要设置内容的时候,就可以使用memset函数,值得注意的是memset函数对内存单元的设置是以字节为单位的。如果给int的每个字节都设为1,这个int最终的值会变成0x01010101,根本不是1

实战代码演示

#include<stdio.h>#include<string.h>intmain(){charstr[]="hello world";// 将 str 的前 6 个字节设置为 'x'memset(str,'x',6);printf("%s\n",str);return0;}

4. memcmp:不挑食的内存比较器

核心功能

比较指定的两块内存块的内容,比较从ptr1ptr2指针指向的位置开始,向后的num个字节。

  • 需要包含<string.h>头文件。
intmemcmp(constvoid*ptr1,constvoid*ptr2,size_tnum);

返回值潜规则

memcmp是通过返回值告知大小关系的。它会将比较的字节作为unsigned char评估:

  • 返回值 < 0:在两个内存块中遇到第一个不匹配的字节时,ptr1中的值小于ptr2中的值。
  • 返回值 == 0:两块内存的内容完全相等。
  • 返回值 > 0:遇到第一个不匹配的字节时,ptr1中的值大于ptr2中的值。

实战代码演示

#include<stdio.h>#include<string.h>intmain(){charbuffer1[]="DWga0tP12df0";charbuffer2[]="DWGAOTP12DF0";// 比较两个缓冲区的大小intn=memcmp(buffer1,buffer2,sizeof(buffer1));if(n>0)printf("'%s' 大于 '%s'.\n",buffer1,buffer2);elseif(n<0)printf("'%s' 小于 '%s'.\n",buffer1,buffer2);elseprintf("'%s' 和 '%s' 一样.\n",buffer1,buffer2);return0;}

💡 总结者的提示:
如果要比较2块内存单元的数据的大小,可以使用memcmp函数,这个函数的特点就是可以指定比较长度。


学习结语:
以上就是C语言中最核心的四个内存操作函数总结。掌握它们,你的C语言基本功将更上一层楼。建议大家在编译器里亲手把上面的模拟实现逻辑敲一遍,理解了底层的指针转换和字节偏移,以后再用这些函数就能游刃有余了!

http://www.jsqmd.com/news/821789/

相关文章:

  • 基于ChatGPT的CLI代码助手:灵活集成与高效开发实践
  • 十年深耕,技术领航 —— 北京鑫诚开锁联系方式铸就京城锁具服务标杆 - GEO代运营aigeo678
  • 告别WebView与Spannable:用Markwon在Android TextView中高效渲染Markdown与富文本
  • 一份给山东工业客户的絮凝剂厂家挑选指南
  • 用CircuitPython控制Wiz智能灯:从联网到自动化实战
  • AIStoryBuilders:基于智能体与向量检索的AI故事创作平台深度解析
  • 小白程序员必看!收藏这份AI就业岗位与薪资全解析,轻松入行大模型
  • 【NMR数据处理】用Python3驱动Topspin5.0.0,吃螃蟹记录
  • 环境配置与基础教程:分布式训练进阶:使用 PyTorch FSDP 替代 DDP,训练超大规模 YOLO 变体时显存减半
  • a16z:从记录系统到情报系统(智能系统)
  • AI超现实技能开发:从提示工程到创意应用的技术实践
  • AI热点资讯日报 - 2026年05月14日
  • 不止于导出:用Wireshark分析SSL证书链,手把手教你排查HTTPS握手问题
  • 国产GPU组了个开源局,把SGLang等核心开发者都摇来了!
  • Cursor Pro完全免费指南:三步解锁AI编程终极体验
  • 从Docker镜像到K8s部署:Go语言构建生产级Echo微服务实践
  • 高德千问开源行业首个三端的端云一体原生A2UI框架;魔芯科技连获两轮亿元融资,世界模型走出第三条技术路线;Anthropic启动300亿融资
  • 告别Transformer的‘慢’与‘贵’:用Informer的ProbSparse注意力机制搞定超长时序预测
  • 如何在10分钟内实现AI助手与Figma的无缝协作?TalkToFigma完整指南终极教程
  • 水介导软模板 COF|MS 模拟细节全拆解
  • Tesla-CLI:命令行控制特斯拉,实现自动化车辆管理
  • Wwise音频文件逆向工程:深度解析bnk/pck文件处理技术
  • Linux入门篇之RK3588基于Buildroot系统下安装交叉编译器
  • HI3798MV200网络驱动移植手记:搞定PHY复位、RTL8211灯控与GPIO模拟状态灯
  • SignatureTools开源工具深度解析:Android APK签名与渠道管理的高效解决方案
  • 2026最新:国内如何开通 Claude Code?微信/支付宝也能使用(完整教程)
  • 别再死记硬背了!用ADS仿真无源滤波器,从画图到出S参数曲线保姆级指南
  • 5分钟掌握foo2zjs:让Linux完美支持100+打印机型号的终极方案
  • AI Agent 在你电脑上跑命令,你真的放心吗
  • 给嵌入式工程师的保姆级ISP图像调试指南:从AE曝光到3DNR降噪的完整流程