C语言重点——剖析内存函数memcpy和memmove

编程入门 行业动态 更新时间:2024-10-07 20:36:49

C语言重点——剖析内存<a href=https://www.elefans.com/category/jswz/34/1771370.html style=函数memcpy和memmove"/>

C语言重点——剖析内存函数memcpy和memmove

今天来讲讲,复制内存块函数memcpy和移动内存块函数memmove与字符窜函数的区别。

由于字符窜函数strcpy等只能处理字符窜,面对其他类型时它束手无策。而内存函数很好的弥补了字符窜函数的不足,不管任何类型都可以进行处理。

首先看看内存函数的参数和运行场景:

 我们进行一个实例看看它的结果会怎么样:

#include<stdio.h>
#include<string.h>
int main()
{int arr1[5] = { 0 };int arr2[5] = { 1,2,3,4,5 };memcpy(arr1, arr2, 12);for (int i = 0; i < 5; i++){printf("%d", arr1[i]);}return 0;
}

可以看到给定12字节个数。他就会把源数组arr2起始地址开始里面的12字节拷贝到目标数组arr1里面,比字符窜函数strcpy更强大更牛逼。它只需要拷贝字节数,并不要求是什么类型

那我们不妨自己来模拟实现一下memcpy函数,首先分析memcpy的参数:参数1是传目标起始地址,参数2是传源目标起始地址(参数2进行了const修饰,不允许修改内容),参数三是传需要拷贝的字节数, 返回类型是void*类型,声明部分就分析完了

接着我们分析内部实现:因为传参没有规定类型,所以我们对它进行拷贝的时候最好是一个一个字节的进行拷贝。如:(char *)destination=(char *)source,然后destination往后走一个字节,source往后走一个字节,直到把num个字节都拷贝完。但是我们这儿又不能写成(char *)destination++=(char *)source++,因为强制类型转换在这只是临时的,等后边的++结合的时候又变成void *类型了。所以这儿我们选择用destination=(char *)destination+1和source=(char *)source+1来使他们往后走一个字节。因为还要返回目标的起始地址,所以我们一开始用个指针接收一下。现在分析完了,开始操作实现代码。

#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memcpy(void* dest,const void* score,size_t num)
{assert(dest && score);//因为下面要用指针内部内容,所以判断一下不能是空指针void * ret = dest;while (num--){*(char *)dest=*(char *)score;dest=(char *)dest+1;score=(char *)score+1;}return ret;
}
int main()
{int arr1[5] = { 0 };int arr2[5] = { 1,2,3,4,5 };my_memcpy(arr1, arr2, 12);for (int i = 0; i < 5; i++){printf("%d", arr1[i]);}return 0;
}

运行结果我们可以看到我们自己实现的这个函数和库里面的memcpy一样了。

但是有没有想过这种情况,直接情况+图片展现给大家方便了解

假设有数组 arr[10]={1,2,3,4,5,6,7,8,9,10};

情况:如果我们想把从下标为0位置往后的五个元素复制到从下标为2往后的五个元素会怎么样

我们可以看到并不是我们想要的结果,我们想输出12123458910而它输出的是12121218910.让我们画个图看一下内部到底是因为什么

这时候发现倒着存放就可以避免了。

面对这种时候其实库函数还提供了一个函数叫做memmove内存块移动函数。可以直接实现。

用例展示:

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

接着我们自己来看看memmove函数,然后模拟实现一下。

 

现在我们开始实现它,发现只要把第二种的情况补充上就好了。

#include<stdio.h>
#include<assert.h>
#include<string.h>void* my_mmove(void* dest, void* score, size_t num)
{void* ret = dest;assert(dest && score);if (dest < score){while (num--){*(char*)dest = *(char*)score;dest = (char*)dest + 1;score = (char*)score + 1;}}else{while (num--){*((char*)dest + num) = *((char*)score + num);}}return ret;
}
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };my_mmove(arr+2, arr, 20);for (int i = 0; i < 10; i++){printf("%d", arr[i]);}return 0;
}

 

 到这咱们就模拟实现完memmove函数了!

感谢各位朋友的支持!下次再见

更多推荐

C语言重点——剖析内存函数memcpy和memmove

本文发布于:2024-02-06 13:56:01,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1749449.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:函数   内存   重点   语言   memmove

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!