顾名思义,内存函数就是针对内存块(即一块内存)来处理的。
因此本篇所讲的四种内存函数:
- memcpy(内存拷贝)
- memmove(内存移动)
- memset(内存设置)
- memcmp(内存比较)
都是通过对内存块的操作处理来实现其功能的。
注:以下内存函数都需要包含头文件<string.h>
1.memcpy函数的使用和模拟实现
memcpy函数的使用:
我们首先通过它的函数名来对它进行一定的理解
因此memcpy可以译为内存拷贝,可以参考作者的上篇博客http://t.csdnimg.cn/JHXyG中对strcpy函数的讲解来帮助理解memcpy函数。
函数的形式如下图:
第一个参数destination存放的是目标空间的地址
第二个参数source存放的是源空间的地址
函数的作用是从source的地址开始向后复制num(即第三个参数)个字节的数据到destination指向的内存位置,返回的是目标空间的起始地址。
可以看到,数据类型都为void*,这是因为内存函数是对内存进行操作的,内存可以存放各种类型的数据,而void*指针可接收任意空间的地址。
那么具体应该如何操作呢?如图:
由上图可以知道,memcpy是以字节为单位进行拷贝的,而第三个参数告诉我们要拷贝的字节数,因此它并不会同strcpy函数一样遇到\0停下来,而是我们让它拷贝多少就拷贝多少。
memcpy函数的模拟实现:
思路:将源空间(即第二个参数)的地址逐字节赋给目标空间(即第一个参数的地址),每赋完一个字节后两个空间的地址向后增加一字节,再赋值,直到赋完num个字节为止。
代码实现如下:
一般情况下memcpy函数的使用及模拟实现我们已经完成,但如果我们此时想将arr1中的“3,4,5”拷给arr2而是想将arr1中的1,2,3,4,5拷贝到arr1中的3,4,5, 6, 7呢?如图:
如果有细心的小伙伴可能会发现这里有问题,(注意,此时源空间和目标空间是同一块内存)当我们目标空间的3,4分别被源空间的1,2拷贝后,此时arr1中的内存分布如图:接着拷贝下去我们发现会一直进行1,2的循环拷贝,显然不是我们所希望的结果,因此memory函数不负责重叠的拷贝。那这种情况我们该怎么办呢?这就引出来了我们要学习的下一个内存函数——memmove
2.memmove函数的使用和模拟实现
memmove函数的使用:
由上文我们知道memcpy不负责重叠的拷贝,因此当目标空间和源空间有重叠时,我们可以使用memmove函数进行拷贝.
memmove函数的形式如下:
跟memcpy类似,memmove函数的第一个参数为目标空间,第二个参数为源空间,num为拷贝的字节数,返回的是目标空间的地址。作用也是将源空间的num个字节的地址复制拷贝到目标空间。只不过它是可以拷贝重叠的空间的。
使用效果如图:
可以正常将重叠的空间进行拷贝。
memmove函数的模拟实现:
首先我们要想想,当空间重叠时,函数是怎么进行拷贝的呢?
如图,此时目标空间(dest)的起始地址 > 源空间(source)的起始地址:
我们可以将其倒着拷贝。
而当目标空间的起始地址 < 源空间的起始地址时:
我们可以将其从前往后拷贝。
而当目标空间和源空间没有重叠时从前☞后/从后☞前就都可以了
因此memmove函数的模拟实现代码如下:
void* my_memmove(void* dest, void* source, size_t num)
{
void* p = dest;
if (dest < source)//此时目标空间的起始地址<源空间的起始地址,从前☞后拷贝
{
while (num--)
{
*(char*)dest = *(char*)source;
dest = (char*)dest + 1;
source = (char*)source + 1;
}
}
else//从后☞前拷贝
{
while (num--)
{
*((char*)dest + num) = *((char*)source + num);
}
}
return p;
}
3.memset (内存设置)函数的使用
函数形式如下:
如图,第一个参数(ptr)为我们要设置的内存
第二个参数(value)是我们想要的内容
第三个参数(num)为我们要改变的字节数
因此,memset是用来设置内存的,将内存中的值以字节为单位设置成我们想要的内容
示例如下:
4.memcmp(内存比较)函数的使用
memcmp函数的学习可以参考http://t.csdnimg.cn/vsA0n中的strcmp函数
memcmp函数形式如下:
作用:比较ptr1和ptr2指针指向的位置开始的向后num个字节
返回值如下:
既然我们已经知道了memcmp函数的作用,那就开始实操了,代码实现如下:当前num个字节相等时返回0。
当arr1<arr2时返回<0的数字
当arr1>arr2时返回>0的数字
完结撒花~
创作不易,来个三连支持一下吧亲🌹🌹~