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

#C语言——学习攻略:探索内存函数--memcpy、memmove的使用和模拟实现,memset、memcmp函数的使用

🌟菜鸟主页:@晨非辰的主页

👀学习专栏:《C语言学习》

💪学习阶段:C语言方向初学者

⏳名言欣赏:"代码是写给人看的,顺便让机器执行。"


目录

1. memcpy函数

1.1 memcpy函数使用示范

1.2 模拟实现memecpy函数(--请看注释:字节访问、临时强转)(要会复现)

2. memmove函数

2.1 memmove函数使用示范

2.2 模拟实现memmove函数(要会复现)

3. memset函数

3.1 memset函数使用示范

3.2 使用总结

4. memcmp函数

4.1 memcmp函数使用演示

4.2 使用总结


1. memcpy函数

void* memcpy(void* destination, const void* source, size_t num);

--介绍:

--功能:

  • 函数 memcpy 从 source 的位置开始向后复制 num 个字节的数据到 destination 指向的内存位置;
  • 这个函数在遇到'\0'的时候不会停下来;
  • 如果 source 和 destination 有任何的重叠,复制的结果都是未定义的(内存重叠的情况在 memmove中有介绍 );
  • memcpy 的使用需要包含<string.h>;

--参数:

  • destination:指针,指向目标空间,拷贝的数据存放在这里;
  • source:指针,指向源空间,要拷贝的数据从这里来;
  • num:要拷贝的数据占据的字节数;

--返回值:拷贝完成后,返回目标空间的起始地址

1.1 memcpy函数使用示范

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

1.2 模拟实现memecpy函数(--请看注释:字节访问、临时强转)(要会复现)

#include <string.h>
#include <assert.h>
void* my_memcpy(void* dest, const void* src, size_t num) 
{//先将dest初始地址存上,防止后续操作覆盖初始地址void* ret = dest;assert(dest && src);//循环直接将字节数当条件,更简单while (num--){//因为都是void*类型,无法直接解引用,在这里进行强转//强转为char*, 是因为可以按照1字节进行访问,但是只有char*可许,其余不行*(char*)dest = *(char*)src;//强转是临时的,再次强转dest = (char*)dest + 1;src = (char*)src + 1;}return ret;
}
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[20] = { 0 };my_memcpy(arr2, arr1, 16);for (int i = 0; i < 4; i++){printf("%d ", arr2[i]);}return 0;
}

2. memmove函数

void* memmove(void* destination, const void* source, size_t num);

--介绍:

--功能:

  • 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的;
  • 使用需要包含<string.h>;

--参数:

  • destination:指针,指向目标空间,拷贝的数据存放在这里;
  • source:指针,指向源空间,要拷贝的数据从这里来;
  • num:要拷贝的数据占据的字节数;

--返回值:拷贝完成后,返回目标空间的起始地址

2.1 memmove函数使用示范

#include <string.h>
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[20] = { 0 };memmove(arr2, arr1, 16);for (int i = 0; i < 4; i++){printf("%d ", arr2[i]);}return 0;
}

2.2 模拟实现memmove函数(要会复现)

#include <string.h>
#include <assert.h>
void* my_memmove(void* dest, const void* src, size_t num)
{//先将dest初始地址存上,防止后续操作覆盖初始地址void* ret = dest;assert(dest && src);//当dest在左边与src重叠,前往后进行拷贝if (dest < src){*(char*)dest = *(char*)src;//往后进行dest = (char*)dest + 1;src = (char*)src + 1;}//右边重合、没重合:后向前else{while (num--){*((char*)dest + num) = *((char*)src + num);}}return ret;
}
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };//int arr2[20] = { 0 };my_memmove(arr1 + 2, arr1, 16);for (int i = 0; i < 4; i++){printf("%d ", arr1[i]);}return 0;
}


3. memset函数

void* memset(void* ptr, int value, size_t num);

--介绍:

--功能:

  • memset 函数是用来设置内存块的内容的,将内存中指定长度的空间设置为特定的内容;
  • 使用需要包含<string.h>;

--参数:

  •  ptr:指针,指向要设置的内存空间,也就是存放了要设置的内存空间的起始地址;
  • value:要设置的值,函数将会把 value 值转换成 unsigned char 的数据进行设置的。 也就是以字节为单位来设置内存块的;
  • num:要设置的内存长度,单位是字节

--返回值:

 返回的是要设置的内存空间的起始地址。

3.1 memset函数使用示范

#include <string.h>
int main()
{char arr[] = "hello world";memset(arr + 2, 'x', 6);printf("%s", arr);return 0;
}

--但是注意,下面这串代码就不能实现:

int main()
{int arr1[] = { 0 };memset(arr1, 1, 40);return 0;
}

--但是可以设置为0.

3.2 使用总结

--当有一块内存空间需要设置内容的时候,就可以使用memset函数,值得注意的是memset函数对内存单元的设置是以字节为单位的。


4. memcmp函数

int memcmp(const void* ptr1, const void* ptr2, size_t num);

--介绍:

--功能:

  • 比较指定的两块内存块的内容,比较从ptr1和ptr2指针指向的位置开始,向后的num个字节;
  • 使用需要包含<string.h>;

--参数:

  • ptr1:指针,指向一块待比较的内存块;
  • ptr2:指针,指向另外一块待比较的内存块;
  • num:指定的比较长度,单位是字节;

--返回值:

4.1 memcmp函数使用演示

#include <string.h>
int main()
{char arr1[] = "abcdefgh";char arr2[] = "abcdef";int ret;ret = memcmp(arr1, arr2, 5);if (ret > 0)printf(">\n");else if (ret < 0)printf("<\n");elseprintf("=");return 0;
}

4.2 使用总结

--如果要比较2块内存单元的数据的大小,可以使用 memcmp 函数,这个函数的特点就是可以指定比较长度memcmp 函数是通过返回值告知大小关系的。


相关知识回顾:

#C语言——学习攻略:探索字符函数和字符串函数(一)--字符分类函数,字符转换函数,strlen,strcpy,strcat函数的使用和模拟实现
#C语言——学习攻略:探索字符函数和字符串函数(二)--strcmp、strstr的使用和模拟实现以及strncpy、strncat、strncmp、strock、strerror函数的使用

结语:本篇文章到此结束,呈现了内存函数的内容,内涵丰富,大家要多次回顾,如果这篇文章对你的学习有帮助的话,欢迎一起讨论学习,你这么帅、这么美给个三连吧~~~

http://www.lryc.cn/news/611855.html

相关文章:

  • flex布局:容器的justify-content属性
  • CEH、OSCP、CISP、CISSP 四大网络安全认证攻略
  • 【hot100】无重复字符的最长子串-Python3
  • duiLib 编译时复制资源目录到exe同级目录
  • 推动本地流智能:基于 Apache Kafka 与 Flink 的实时机器学习实践
  • 无需SCADA/OPC,实现直接与西门子PLC Web API通讯实现数据读写(一)
  • Mysql如何迁移数据库数据
  • 【自动驾驶】《Sparse4Dv3 Advancing End-to-End 3D Detection and Tracking》论文阅读笔记
  • 工业协议转换终极武器:EtherCAT转PROFINET网关的连接举例
  • Spring Boot全局异常处理与日志监控实战指南
  • 从Navisworks到定制化BIM系统:HOOPS Exchange如何实现高效3D格式解析?
  • 【公考】----申论篇
  • 测试单节点elasticsearch配置存储压缩后的比率
  • 20250806给PRO-RK3566开发板在Buildroot系统下扩大rootfs分区2GB
  • 移动端网页调试实战,跨设备兼容与触控交互问题排查全流程
  • Class30数据增广
  • 【docker】完整 Dockerfile 示例和构建运行指南
  • SmartX 用户建云实践|宝信软件:搭建“双架构”私有云平台,灵活满足多种业务需求
  • Bug 记录:SecureRandom.getInstanceStrong()导致验证码获取阻塞
  • Python爬虫 urllib 模块详细教程:零基础小白的入门指南
  • Unity3D水下场景与游泳系统开发指南
  • Scrapy(一):轻松爬取图片网站内容​
  • 安宝特方案丨工业AR+AI质检方案:致力于提升检测精度与流程效率
  • linux-系统性能监控
  • Python爬虫实战:研究spiderfoot工具,构建网络情报收集系统
  • python每日一题 贪心算法
  • 线程-线程池篇(二)
  • 基于Hadoop的木鸟民宿数据分析与可视化、民宿价格预测模型系统的设计与实现
  • 使用 gptqmodel 量化 Qwen3-Coder-30B-A3B-Instruct
  • MyBatis基础操作完整指南