赞
踩
今天来讲讲,复制内存块函数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函数了!
感谢各位朋友的支持!下次再见
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。