目录

1. memcpy

EX:

PS:

模拟实现:

2. memmove

EX:

​编辑

模拟实现:

3. memcmp

EX:

PS:

模拟实现:

4. memset

EX:

模拟实现:


1. memcpy

memcpy函数的作用为:将source指向的地址拷贝num个字节到destination指向的的地址

(注意!这里时拷贝num个字节!)

返回类型为void*类型,返回destination指向的起始地址

前两个参数均为void*类型,

第一个参数为拷贝的目的地的起始地址;

第二个参数为要拷贝的内容所在的起始地址;

第三个参数为size_t类型,即无符号整型类型,num为要拷贝的字节数;

与strnmpy函数差不多,只不过memcpy函数可以拷贝任意类型的数据。

EX:

#include <stdio.h>
#include <string.h>
int main()
{int arr1[15] = { 0 };int arr2[] = { 1,2,3,4,5,6,7,8,9,10 };memcpy(arr1, arr2, 20);return 0;
}

该样例是将arr2指向的地址的前20个字节的内容拷贝到arr1指向的地址中,因为这些数据的类型均为int类型,一个int类型占4个字节,拷贝20个字节就是拷贝5个int类型的数据。

#include <stdio.h>
#include <string.h>
int main()
{float arr1[15] = { 0 };float arr2[] = { 1.0f,2.0f,3.0f,4.0f,5.0f,6.0f,7.0f };memcpy(arr1, arr2, 20);return 0;
}

该样例是拷贝float类型数据,同理,拷贝20个字节的内容就是拷贝5个float类型的数据。

PS:

该函数遇到'\0'也不会停止,直到拷贝完规定的字节为止~

#include <stdio.h>
#include <string.h>
int main()
{int arr1[15] = { 0 };int arr2[] = { 1,2,3 };memcpy(arr1, arr2, 20);return 0;
}

arr2中只有3个int类型的数据,可是memcpy函数要拷贝20个字节的数据,

通过监视我们可以看到,拷贝完3个int类型的数据之后,不管后面是不是'\0',只要没有拷贝完规定的字节数,都会往后继续拷贝~

模拟实现:

创建一个my_memcpy函数,模拟实现memcpy函数功能:

void* my_memcpy(void* dest, const void* sur, size_t num)//返回值类型参数类型与原函数保持一致
{//dest所指向的字符串需要被修改,不用const保护,src所指向的字符串不需要被修改用const修饰保护assert(dest && sur);//断言一下,保证两个指针均不为空指针,若为空指针则中止程序并报错void* ret = dest;//创建一个char*变量保存起始地址,后面需要返回起始地址while (num--)//控制拷贝几个字节{*(char*)dest = *(char*)sur;//char类型为一个字节,强制类型转化为char类型就可以一个节一个字节拷贝(char*)dest += 1;          //强制类型转化为char*再+1,就跳过一个字节大小(char*)sur += 1;           //同理}return ret;     //返回所保存的起始地址
}
int main()
{char arr1[] = "abcdef";char arr2[] = "qwer";my_memcpy(arr1, arr2, 4);printf("%s\n", arr1);return 0;
}

该函数不能拷贝重合的情况!

2. memmove

memmove函数的作用:与memcpy函数的作用相同~

和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。

如果源空间和目标空间出现重叠,就得使用memmove函数处理。

EX:

int main()
{int arr[15] = { 1,2,3,4,5,6,7,8,9,10 };memmove(arr + 2, arr, 20);return 0;
}

该样例就十分直观了,将arr内存块的内容拷贝20个字节到arr+2的内存块,

显然有重叠的部分,但是memmove函数可以完美解决重叠的问题~

模拟实现:

创建一个my_memmove函数,模拟实现memmove函数功能:

void* my_memmove(void* dest, const void* sur, size_t num)
{assert(dest && sur);void* ret = dest;     //以上代码与前几个模拟函数类似,这里就不多赘述了if (dest < sur){while (num--){*(char*)dest = *(char*)sur;  //强制类型转化为char*类型,因为char类型就是占用一个字节dest = (char*)dest + 1;sur = (char*)sur + 1;}}else{while (num--){*((char*)dest + num) = *((char*)sur + num);//这里不用再-1了,while判断之后就自动-1了。}}return ret;
}
int main()
{char arr1[] = "abcdef";my_memmove(arr1 + 2, arr1, 4);printf("%s\n", arr1);return 0;
}

这里只解释拷贝重合的情况:(其余都与my_memcpy函数类似)

第一种情况:src在dest前面

若从前向后拷贝那么重合的部分就会被提前更改,导致后面拷贝的内容是已经被更改完的,结果错误

所以,这种情况我们需要从后向前拷贝,先拷贝重叠部分,之后被覆盖的时候就没有影响了

第二种情况:src在dest后面

这种情况也是先拷贝重叠部分,即从前向后拷贝,之后重叠部分被覆盖的时候也是没有影响的

3. memcmp

memcmp函数的作用:比较ptr1与ptr2内存块的num个字节的内容~

前两个参数就是要比较的内存块的地址;

第三个参数就是要比较的字节数。

返回值为int类型:

EX:

int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[] = { 1,2,3,0,0 };int ret = memcmp(arr1, arr2, 12);printf("%d\n", ret);return 0;
}

前12个字节的内容都一样,所以返回0

PS:

要注意的是:

这里比较的以字节为单位的,所以是要牵扯到大小端存储的~

不了解大小端存储的可以看这篇文章:大小端存储解析

以上面的例题为例:

小端存储:

大端存储:

比较12个字节是一样的,但是比较13个字节就会发现结果不一样了!

小端存储:

最后一个字节arr1中为04;arr2中为00;

arr1比arr2大~

大端存储:

最后一个字节arr1中为00;arr2中也为00;

arr1与arr2一样大~

模拟实现:

创建一个my_memcmp函数,模拟实现memcmp函数的功能:

int my_memcmp(const void* ptr1, const void* ptr2, size_t num)
{assert(ptr1 && ptr2);   //以上代码与前面的模拟函数类似,这里就不多赘述了while (num--){if (*(char*)ptr1 == *(char*)ptr2){(char*)ptr1 += 1;(char*)ptr2 += 1;}elsereturn *(char*)ptr1 - *(char*)ptr2;}return 0;
}
int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[] = { 1,2,3,0,0 };int ret = my_memcmp(arr1, arr2, 12);printf("%d\n", ret);return 0;
}

该函数与我这个系列的(二)号文章中的strncmp函数模拟原理几乎相同,只不过多了个强制类型转换,也不用判断'\0'

有兴趣的可以看看那篇文章:strn...类字符串函数详解及模拟实现

该函数也是分大小端区别的!

4. memset

memset函数的作用:修改内存信息

第一个参数是要修改的内存的起始位置;

第二个参数是要修改成为的内容;

第三个参数是要修改的字节数;

EX:

int main()
{int arr[] = { 1,2,3,4 };memset(arr, 1, 8);int i = 0;for (i = 0; i < 4; i++){printf("%d ", arr[i]);}return 0;
}

通过观察内存我们可以看到将arr起始的后八个字节的内容都改成了1

模拟实现:

创建一个my_memset函数,模拟实现memset函数的功能:

void* my_memset(void* ptr, int value, size_t num)
{assert(ptr);while (num--)  //控制更改几个字节的内容{*(char*)ptr = (char)value;  //强制类型转化为char*与char类型进行赋值,因为char类型占一个字节(char*)ptr += 1;     //强制类型转化为char*类型,+1,跳过一个字节的大小}
}
int main()
{int arr[] = { 1,2,3,4 };my_memset(arr, 1, 8);int i = 0;for (i = 0; i < 4; i++){printf("%d ", arr[i]);}return 0;
}

赶紧来修炼内功发~内存函数详解大全-memcpy、memmove、memcmp相关推荐

  1. 赶紧来修炼内功~字符串函数详解大全(二)

    目录 1.strncpy 重点: 模拟实现: 2.strncat 重点: 模拟实现: 3.strncmp 重点: 模拟实现: 写在最后: 1.strncpy 该函数包含三个参数,前两个参数与上一篇文章 ...

  2. 赶紧来修炼内功~字符串函数详解大全(三)

    目录 1. strstr 2. strtok 重点: 3. strerror perror: 1. strstr 该函数是用来查找str1字符串中是否含有str2字符串    存在:返回str2字符串 ...

  3. 赶紧来修炼内功~字符串函数详解大全(一)

    目录 1.strlen 重点: 模拟实现: 法一: 法二: 法三: 2.strcpy 重点: 模拟实现: 3.strcat 重点: 模拟实现: 4.strcmp 重点: 模拟实现 1.strlen s ...

  4. 【C语言】字符串和内存函数详解

    文章目录 1. 求字符串长度 strlen

  5. 共享内存映射之mmap()函数详解

    转 共享内存映射之mmap()函数详解 /span> 查看全文 http://www.taodudu.cc/news/show-3175071.html 相关文章: 子集生成(二进制法,逐步生成 ...

  6. FatFs文件系统Nandflash驱动函数详解

    FatFs文件系统Nandflash驱动函数详解 转载 2015-08-06 14:43:27 标签:nandflash驱动函数详fatfs文件系统nandfla 本文讲解FatFs文件系统 下需要的 ...

  7. Java内存溢出详解之Tomcat配置

    Java内存溢出详解 转自:http://elf8848.iteye.com/blog/378805 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError ...

  8. C语言网络编程:accept函数详解

    文章目录 前言 函数描述 代码实例 如何得到客户端的IP 和 端口号 前言 当使用tcp服务器使用socket创建通信文件描述符,bind绑定了文件描述符,服务器ip和端口号,listen将服务器端的 ...

  9. 【C++】C++对象模型:对象内存布局详解(C#实例)

    C++对象模型:对象内存布局详解 0.前言 C++对象的内存布局.虚表指针.虚基类指针解的探讨,参考. 1.何为C++对象模型? 引用<深度探索C++对象模型>这本书中的话: 有两个概念可 ...

最新文章

  1. 2020届秋招个人总结
  2. Flash与组件:国外收费组件网站
  3. maven工程下 读取resource下配置文件
  4. mac终端一次命令在多个虚拟机执行_Windows给力!可以扔掉Linux虚拟机了!
  5. 使用工具分析 SAP UI5 应用前端执行的性能问题
  6. 初一模拟赛总结(2019.4.13)
  7. 计算机网络(二十三)-网络层-概述与数据交换方式
  8. 除了“团队牛”还有“饭菜香”,百度 IDL 招聘算法实习生
  9. [SQL SERVER] 优化SQL Server 2000的设置
  10. 蠕虫病毒往往是通过进入计算机系统,2012年甘肃省三职生计算机考试题
  11. Pytorch 学习笔记:
  12. Unity 模拟两个小球位置变化,长度也动态变化
  13. 顶会两篇论文连发,华为云医疗AI低调中崭露头角
  14. linux系统双网卡不能同时启动,针对RHEL中双网卡IP不能同时被访问的解决方法
  15. 【数学计算】点乘/点积/内积/数量积/叉乘/外积/叉积/向量积
  16. 刷程序对车危害_刷ecu非常后悔,刷程序对车危害有多大
  17. MySQL数据库——备份与恢复
  18. 60个必备NOIP模板 python算法模板
  19. elementUi基础入门学习
  20. 多线程相关知识点总结

热门文章

  1. 怎样将pdf压缩得很小?如何把pdf压缩到最小?怎么把pdf压缩到最小?如何把pdf文档压缩变小?怎么将pdf文档压缩至更小?怎么把pdf压缩到最小方法软件网站有哪些?
  2. 数据中心(DC)核心交换机和普通交换机的区别
  3. vue使用 moment.js 格式化时间(获取当前日期的周一和周日)
  4. input输入框去除历史记录
  5. 计算机毕设(附源码)JAVA-SSM快递代收系统
  6. 今年上半年消费市场趋势_您今年需要了解的8种趋势
  7. 常见的百度云搜索引擎入口合集
  8. html是什么1003无标题,爱特漫画1003无标题
  9. 石家庄IT培训业转型要诀:出品,用户,服务
  10. 安装sql server 过程(为了使用SQL Server Management Studio)