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

【C语言】深入理解C语言内存操作函数:memcpy、memmove、memset与memcmp


目录

  • 1. memcpy函数的使用与模拟实现
    • 1.1 函数介绍
    • 1.2 使用示例
    • 1.3 模拟实现
  • 2. memmove函数的使用与模拟实现
    • 2.1 函数介绍
    • 2.2 使用示例
    • 2.3 模拟实现
  • 3. memset函数的使用
    • 3.1 函数介绍
    • 3.2 使用示例
  • 4. memcmp函数的使用
    • 4.1 函数介绍
    • 4.3 使用示例

在这里插入图片描述

🔥个人主页:@月夜的风吹雨
🎥作者简介: C++研发方向学习者
📖个人专栏:《C语言》
🌄人生格言: 任何一个伟大的思想,都有一个微不足道的开始。

前言:在C语言编程中,对内存的直接操作是非常常见且重要的任务。为了高效、安全地处理内存数据,C标准库提供了一系列内存操作函数。本文将详细介绍memcpy、memmove、memset和memcmp这四个函数的使用方法、区别以及模拟实现,帮助大家更好地理解并掌握这些基础但强大的工具。

1. memcpy函数的使用与模拟实现

1.1 函数介绍

memcpy函数的原型如下:
在这里插入图片描述
在这里插入图片描述
该函数用于将source指向的内存地址开始的num个字节数据复制到destination指向的内存地址。

注意memcpy不会因为遇到'\0'而停止复制,且如果源地址与目标地址存在重叠,其行为是未定义的

1.2 使用示例

#include <stdio.h>
#include <string.h>int main() {int arr1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};int arr2[10] = {0};memcpy(arr2, arr1, 20); // 复制前20个字节(即5个int)for (int i = 0; i < 10; i++) {printf("%d ", arr2[i]);}return 0;
}

输出结果:

1 2 3 4 5 0 0 0 0 0

1.3 模拟实现

void* my_memcpy(void* dst, const void* src, size_t count) {void* ret = dst;assert(dst && src); // 确保指针有效while (count--) {*(char*)dst = *(char*)src;dst = (char*)dst + 1;src = (char*)src + 1;}return ret;
}

在while循环中为何不能使用*(char*)dst++ = *(char*)src++? 这是因为对dest的 (char*)强制类型转换只是临时性的,执行后dest仍会恢复为void类型指针,而void指针不支持自增运算。

🔍注意:该实现是按字节从前向后复制,适用于非重叠内存区域。

2. memmove函数的使用与模拟实现

2.1 函数介绍

memmove函数的原型与memcpy相同:
在这里插入图片描述
在这里插入图片描述
memcpy不同的是,memmove可以处理内存重叠的情况。它是更安全的复制函数。

2.2 使用示例

#include <stdio.h>
#include <string.h>int main() {int arr1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};memmove(arr1 + 2, arr1, 20); // 将前5个元素复制到第3个位置开始for (int i = 0; i < 10; i++) {printf("%d ", arr1[i]);}return 0;
}

输出结果:

1 2 1 2 3 4 5 8 9 10

2.3 模拟实现

void* my_memmove(void* dest, const void* src, size_t num) {assert(dest && src);void* ret = dest;if ((char*)dest <= (char*)src || (char*)dest >= (char*)src + num) {//往前交换,先交换src前面的字节while (num--) {*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}else {//先定位交换的位置dest = (char*)dest + num - 1;src = (char*)src + num - 1;//往后交换,先交换src后面的字节while (num--) {*(char*)dest = *(char*)src;dest = (char*)dest - 1;src = (char*)src - 1;}}return ret;
}

🛠️ 提示: memmove通过判断内存是否重叠,选择不同的复制方向,确保数据正确性。

3. memset函数的使用

3.1 函数介绍

memset函数的原型如下:

在这里插入图片描述

在这里插入图片描述
该函数用于将ptr指向的内存区域的前num个字节设置为value的值(按字节设置)。

3.2 使用示例

#include <stdio.h>
#include <string.h>int main() {char str[] = "hello world";memset(str, 'x', 6); // 将前6个字符设为'x'printf("%s", str);return 0;
}

输出结果:

xxxxxxworld
  • 💡 用途: 常用于初始化数组、清空缓冲区等。

4. memcmp函数的使用

4.1 函数介绍

memcmp函数的原型如下:
在这里插入图片描述
在这里插入图片描述
该函数用于比较ptr1ptr2指向的内存区域的前num个字节的内容。

返回值含义
<0ptr1小于ptr2
0内容相等
>0ptr1大于ptr2

4.3 使用示例

#include <stdio.h>
#include <string.h>int main() {char buf1[] = "DWga0tP12df0";char buf2[] = "DWGA0TP12DF0";int n = memcmp(buf1, buf2, sizeof(buf1));if (n > 0) printf("'%s' > '%s'\n", buf1, buf2);else if (n < 0) printf("'%s' < '%s'\n", buf1, buf2);else printf("'%s' == '%s'\n", buf1, buf2);return 0;
}

输出结果:

'DWga0tP12df0' > 'DWGA0TP12DF0'
  • 📌 注意: 比较是按字节进行的,不考虑字符串结束符。

理解并熟练使用这些内存操作函数,是每一位C语言程序员的基本功。它们不仅在底层开发中广泛应用,也在高性能计算、嵌入式系统等领域中发挥着重要作用。

📚更多C语言教程,欢迎关注我的CSDN博客!
👉月夜的风吹雨 《C语言》

http://www.dtcms.com/a/365582.html

相关文章:

  • Directus本地搭建遇到的问题及解决方案
  • 基于51单片机音乐喷泉设计频谱彩灯音乐盒播放器
  • gdb调试死锁
  • 安卓APP上架之安卓App备案的三要素:包名、公钥与MD5签名的深度解析-优雅草卓伊凡
  • Java设计模式之创建型—建造者模式
  • 零基础学英语APP推荐:一个程序员的亲测有效逆袭攻略
  • 普通人也能走的自由之路
  • 限流、降级、熔断的区别和应用场景
  • 9月3日星期三今日早报简报微语报早读
  • 多路复用 I/O 函数——`select`函数
  • SystemServer 启动流程
  • EDVAC:现代计算机体系的奠基之作
  • 影像服务免费方案:GIS Server让GeoTIFF数据在山海鲸中直观呈现
  • PyTorch实战——ResNet与DenseNet详解
  • 关于嵌入式学习——嵌入式硬件2
  • Mac电脑Tomcat+Java项目中 代码更新但8080端口内容没有更新
  • 打破信息洪流:微算法科技(NASDAQ:MLGO)推出一种移动互联网环境下数字媒体热点挖掘算法
  • 01-Redis 发展简史与核心定位解析:从诞生到三大产品矩阵
  • 微信小程序预览和分享文件
  • 从检索的角度聊聊数据结构的演进​
  • Vue 评论组件设计 V1.0
  • 关于linux软件编程15——数据库编程sqlite3
  • Spring Boot配置error日志发送至企业微信
  • EI会议:第七届人工智能与先进制造国际会议(AIAM 2025)
  • 多智能体协作系统(CrewAI)
  • 素材合集!直播间带货音乐BGM合集,抖音直播间常用热门音乐合集,根据中文分类,方便查找
  • AI重塑SaaS:从被动工具到智能角色的技术演进路径
  • Shell 三剑客之 awk 命令详解(理论+实战)
  • Datawhale AI夏令营复盘[特殊字符]:我如何用一个Prompt,在Coze Space上“画”出一个商业级网页?
  • SDK介绍