目录
1.memcpy的使用和模拟实现
1.1memcpy的使用
1.2memcpy的模拟实现
2.memmove的使用和模拟实现
2.1memmove的使用
2.2memmove函数的模拟实现
3.memset函数的使用
3.1memset函数的使用
3.2memset函数的注意事项
4.memcmp函数的使用
创作不易,对您有帮助的话还望一键三连,谢谢!!!
1.memcpy的使用和模拟实现
void*memcpy(void*destination,const void*source,size_t num);
•memcpy函数将从source的位置开始向后复制num个字节的数据拷贝到destination中指向的内存位置。
•memcpy遇到'\0'不会停下来;
•如果destination 和source有任何的重叠,那么函数复制的结果都是未定义的
1.1memcpy的使用
上面一段代码我们把arr2的7个字节的数据(即“abcdef”)拷贝到了arr1中,并将arr1的内容打印了出来。需要注意的是memcpy拷贝时是以字节为单位的。
1.2memcpy的模拟实现
当我们知道了memcpy原理和如何使用后,那么memcpy又该如何模拟实现呢?
模拟实现时,我们可能会有这样的疑惑:为什么指针类型不能是int*或者是其他类型呢?
假设我们把它改成int*,那么当我们要把src中开始的7个字节的内容复制到dest中,这时该怎么办呢?所以说,将参数类型写成void*,可以在函数体内部根据实际需求进行强制类型转换,从而实现各种类型的数据复制。
如上图代码,我么实现了memcpy函数的模拟实现,这与我们上次讲的字符串函数中的strcpy大同小异,只不过是memcpy应用范围更广,而strcpy一般用于字符串拷贝。
那么我们上面讲到:如果destination 和source有任何的重叠,那么函数复制的结果都是未定义的
那结果是这样吗,我们写段代码测试一下:
这段代码,不出意外的话结果应该是1,2,1,2,3,4,5,8,9,10;
我们运行一下:
结果却是这样,这是为什么呢?接下来我们来分析一下:
原来在复制时,改变了src后面的内容,所以才会出现上述的结果。因此我们在使用memcpy时要注意,dest和src的不能有重叠,那么如果源内存块和目标内存块有重叠,我们又该怎么办呢?那就要使用接下来我们要讲的memmove函数。
2.memmove的使用和模拟实现
2.1memmove的使用
void*memmove(void*destination,const void* source,size_t num);
我们把这个函数的参数和memcpy函数的参数比较一下:
好家伙,一模一样。那么它俩有什么差别呢?
memmove和memcpy的差别就是memmove函数处理的源内存块和⽬标内存块是可以重叠的。
那么memmove函数如何使用呢?我们来看下面一段代码:
如上图代码,我们简单的运用了一下memmove函数。
2.2memmove函数的模拟实现
模拟实现时,我们要想到dest 和src的起始位置不同,那么实现方式也会有所不同,所以我们要分情况讨论,原因如下图所示:
知道了这个原理后,接下来的代码就比较简单了:
3.memset函数的使用
3.1memset函数的使用
void* memset(void*ptr,int val,size_t num);
memset函数是用来设置内存的,将指定内存中的值以字节为单位设置成val。
如图,上面一段代码,我们把str前六个字节,设置成了'x'
这就是memset函数的简单应用
3.2memset函数的注意事项
memset函数是以字节为单位设置内存中的值的,所以,在修改多字节类型数据(如int),要多加注意,下图为一个典型的错误示例:
如上图所示,我们本意是想把arr中前五个元素的值修改为1,但是结果却是上面一个大数字,这是为什么呢?我们来调试一下:
我们发现memset函数把arr前五个元素每个字节都修改成了1,所以才会变成一个大的数字。
4.memcmp函数的使用
int memcmp(const void*ptr1,const void* ptr2,size_t num);
这个函数和字符串函数我们所讲的strcmp功能基本相同,所以在不在详细讲解,简单应用如下图代码: