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

C语言函数:内存函数memcpy()以及实现

C语言函数:内存函数memcpy()

引言:

#define _CRT_SECURE_NO_WARNINGS#include <stdlib.h>int main()
{int arr1[20] = { 1,2,3,4,5,6,7,8,9 };int arr2[20] = { 0 };strcpy(arr2, arr1);return 0;
}

        

         strcpy函数:C语言函数:字符串函数及模拟实现strlen() 、strcpy()、 strcat()_srhqwe的博客-CSDN博客

        以上代码,如果用strcpy()函数,想将arr1拷贝到arr2中,要明白strcpy()是字符串拷贝函数,这样使用strcpy()会出现问题:

        类型不一样arr1和arr2是int类型,strcpy只接收char*类型。如果强行将arr1内容拷贝到arr2中,当是小端存储时,strcpy()访问完一个字节01后,当要访问第二个字节00时,发现00是ASCII码值为0,strcpy会认为这是\0,然后停止向后继续拷贝。最后arr2只拷贝了01过去,arr2的则变成了0.

        因为strcpy不能将arr1拷贝到arr2,因此就急需一个函数是针对内存块进行拷贝的。只要你是针对内存块拷贝,无论你是何种类型,何种数据都可以进行拷贝:

memcpy()函数:

        头文件:#include <string.h>

参数:

         函数类型是void*指针,说明返回的是任何类型指针的destination。

        destination和source与strcpy()一样,只是类型变成了void*

        size_t num是最关键的,意思是:从destination中拷贝num个字节到source中,

        

函数使用:

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

         此时要将arr1中的1,2,3,4,5拷贝到arr2中,一个int是4字节,5个int就是20字节,因此num传入20,结果:

        

         其中20可以使用sizeof(int),算出一个int大小,再x上5,也可以得到20

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

memcpy函数的实现:

        创建:void* my_memcpy(void* dest, const void* sour, size_t num)

        size_t == (unsigned)int----------只有正数

        

#define _CRT_SECURE_NO_WARNINGS#include <string.h>void* my_memcpy(void* dest, const void* sour, size_t num)
{for (int i = 0; i < num; i++){*((char*)dest + i) = *((char*)sour+i);}return dest;
}int main()
{int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[10] = { 0 };my_memcpy(arr2, arr1,5*sizeof(int));return 0;
}

        因为dest是void*,不能通过+1或++之类的操作符对他进行改变。因为计算机并不知道void*+1跳多少字节。如果+1首先代码行就会变成红色(出错)

        这里将dest和sour强制类型转换成char*,那么每次+i就能移动一个字节。可以保证每个字节都做出了改变。

        如果强制类型转换成int或其他的类型,这个函数就有了局限性。+1就跳4字节。那么中间这四个字节没有做出改变,如果此时传入char类型的数据,那么就会使得内容缺失。

        

memcpy内存重叠问题:

        

#define _CRT_SECURE_NO_WARNINGS#include <string.h>void* my_memcpy(void* dest, const void* sour, size_t num)
{for (int i = 0; i < num; i++){*((char*)dest + i) = *((char*)sour+i);}return dest;
}int main()
{int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[10] = { 0 };my_memcpy(arr1+2, arr1,5*sizeof(int));return 0;
}

        如以上代码,memcpy函数从arr1拷贝的内容放到了&arr1[2]上。

        如果正常此时按照这样拷贝,arr1中就会变成1,2,1,2,3,4,5,8,9,10

        但是实际上却是:

        

        显然与预期不符,那么为啥呢?

        当从arr1上拿数据放到arr1+2中[3][4]的两个位置变成了1,2;

        arr1[3]和arr[4]以及变成了1,2;此时又从这两个地方拿数据放到[5][6],这两个位置也变成了1,2.以此类推。最后得到了1,2,1,2,1,2,1,8,9,10

        那么如何才能达到预期的效果呢?

        可以使用一个函数:memmove ()

        

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

相关文章:

  • ArcGIS基础:栅格分区转矢量再裁剪面图层【重分类】【栅格转面】
  • vue尚品汇商城项目-day02【11.对axios二次封装+12.接口统一管理】
  • 并发编程-2
  • 万字解析Linux内核调试之动态追踪
  • Spring Boot 各层作用与联系
  • 苦中作乐---竞赛刷题(15分-20分题库)
  • 超详细,多图,PVE安装以及简单设置教程(个人记录)
  • 茴子的写法:关于JAVA中的函数传递语法糖:lambda
  • 动态规划刷题记录(2)
  • 2023年广东省网络安全竞赛——Web 渗透测试解析(超级详细)
  • MI-SegNet阅读笔记
  • 十、MyBatis分页插件
  • EasyCVR平台国标GB28181协议设备接入时,可支持过滤通道类型
  • 玩转git的第1章节:git的理论以及操作规则
  • 【新2023Q2模拟题JAVA】华为OD机试 - 二叉树层次遍历
  • 轻松拿结果-第三部分 同欲 -第六章 有凝聚力才有战斗力
  • chatGPT 会给程序员带来失业潮吗?
  • Vue项目proxyTable跨域配置
  • ubuntu16.04搭建gitlab
  • SSMP综合案例
  • 让你的作品更出色——词云Word Cloud的制作方法(基于python,WordCloud,stylecloud)
  • axios请求拦截器
  • 四个常见的Linux技术面问题
  • 有什么适合程序员查资料的网站
  • (七)手把手带你搭建精美简洁的个人时间管理网站—实现登录与注册的前端代码【源码】
  • Day933.如何将设计最终落地到代码 -系统重构实战
  • 209. 长度最小的子数组
  • 【数据结构与算法】查找(Search)【详解】
  • 一文学会 Spring MVC 表单标签
  • 如何在 Windows10 下运行 Tensorflow 的目标检测?