时间:2021-05-20
使用方法:
#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>#include <string.h>int main(){ char arr1[20] = { 0 }; char arr2[] = "hello world!"; int arr3[10] = { 0 }; int arr4[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int i = 0; memcpy(arr1, arr2, 12); memcpy(arr3, arr4, 16); printf("%s\n", arr1); for (i = 0; i < 10; i++) { printf("%d ", arr3[i]); } return 0;}输出结果:
如果源头和目的地是同一块内存它进行拷贝的时候会出现覆盖的情况。
如:
#include <stdio.h>#include <string.h>int main(){ int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int i = 0; memcpy(arr + 2, arr, 16); for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } return 0;}可以看到它并没有如我们预期的输出来输出结果,我们预期的结果应该是:1 2 1 2 3 4 7 8 9 10
可是memcpy拷贝的时候会覆盖,而C语言对memcpy的标准是只要能实现拷贝即可,不考虑同一块内存拷贝会覆盖的情况,这种情况是由另一个函数来处理。
当然有些编译器对memcpy函数的实现是有优化过的,目前我个人知道的编译器是VS它是对memcpy有优化的,如果拷贝的是同一块内存它不会覆盖,而是如预期的那样进行拷贝。
void* my_memcpy(void* dest, const void* src, unsigned int count);
参数一:void* dest
参数二:void* src
参数三:unsigned int counst
返回类型:void*
assert(dest && src)这个是用来保证代码的健壮性,assert()函数是断言,如果传过来的是空指针,那么就是假因为NULL的值是0,只有两边都为真才不会有提示。
*(char*)dest = *(char*)src因为是void* 类型所以我们要强制转换才能解引用进行拷贝操作,而我们要操作的是一个字节所以转为字符型指针最合适。
++(char*)dest;和上面的同理,要强制类型转换才能进行++和–操作。
使用方法:
#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>#include <string.h>#include <assert.h>int main(){ int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int i = 0; memmove(arr + 2, arr, 16); for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } return 0;}memmove和memcpy的使用方法一样,没什么大区别。
为了处理同块内存的拷贝,这里我们分为了两种方法。
memcpy用的是从前向后拷贝,所以会出现被覆盖的情况。
那么问题来了,我们什么情况才从前向后拷贝和从后向前拷贝呢?
我们可以以src为分界线,如果dest小于src我们就从前向后,这样就避免了src的内容被覆盖之后被拷贝到dest里面去,如果dest大于src,我们就从后向前。
那有人问如果等于呢?等于的话你从前向后还是从后向前不都一样?
所以按照这个思路我们写成两个拷贝顺序,从后向前我们不用思考了,想在我们只需要思考从后向前拷贝。
while (count--) { *((char*)dest + count) = *((char*)src + count); }从后向前我们只需要先得到dest和src末尾的地址就能进行从后向前操作了,count + dest不就得到了末尾了吗?counst + dest得到末尾的\0的地址,但是我们不需要修改\0所以count + dest之前我们对count自减。
后面就不需要dest自减的操作了,因为count每次减一我们就得到前面一个的地址,当count减完了,我们也拷贝完了。
使用案列:
#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>#include <string.h>#include <assert.h>int main(){ char arr1[] = "abcz"; char arr2[] = "abcd"; if ( 0 < memcmp(arr1, arr2, 4)) { printf("大于\n"); } else if(0 > memcmp(arr1, arr2, 4)) { printf("小于\n"); } else { printf("等于\n"); } return 0;}如果count是0的话就直接返回0
while (count-- && *(char*)dest == *(char*)src) { ++(char*)dest; ++(char*)src; }当count个数比较完或者dest不等于src,我们就停止循环。
return *(char*)dest - *(char*)src;直接返回dest - src,如果它们两相等一定返回0,dest小于src返回的是小于0的值,大于则返回大于0的值。
memset是以1字节为单位来修改,第二个参数是要修改成什么字符,第三个参数是修改内存个数以1字节为单位
使用案列:
#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>#include <string.h>int main(){ char arr[10] = { 0 }; int i = 0; memset(arr, '6', 10); for (i = 0; i < 10; i++) { printf("arr[%d]=%c\n", i, arr[i]); } return 0;}把a的值给dest,来进行修改,每次修改一个字节就自增一修改下个字节。
到此这篇关于C语言全部内存操作函数的实现详细讲解的文章就介绍到这了,更多相关C语言内存操作函数的实现内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
C语言编程中有时会遇到一些参数个数可变的函数,本文详细讲解了可变参数函数的实现原理,分享给大家在开始学习C语言的函数的时候,我们就知道函数的参数个数应该是在函数
C语言字符函数、内存函数功能及实现strlen函数(求字符串长度)注意点模拟实现strcpy函数(字符串拷贝函数)注意点模拟实现strcat函数(字符串衔接函数
C语言malloc()函数:动态分配内存空间头文件:#includemalloc()函数用来动态地分配内存空间(如果你不了解动态内存分配,请查看:C语言动态内存
C语言中memcpy函数的用法详解memcpy(内存拷贝函数)c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n
C语言bcopy()函数:复制内存(字符串)头文件:#includebcopy()函数用来复制内存(字符串),其原型为:voidbcopy(constvoid*