C语言内存函数

发布于:2024-04-20 ⋅ 阅读:(25) ⋅ 点赞:(0)

目录

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功能基本相同,所以在不在详细讲解,简单应用如下图代码:

创作不易,对您有帮助的话还望一键三连,谢谢!!!