memmove函数和memcpy函数的模拟实现

简介: memmove函数和memcpy函数的模拟实现

首先我们来了解memmove函数和memcpy函数的使用

memmove函数

他的函数所需参数如下

1.函数memcpy从source的位置开始向后复制num个字节的数据destination 指向的内存位置。

2.这个函数在遇到 ‘\0’ 的时候并不会停下来。

3.如果source和destination有任何的重叠,复制的结果都是未定义的

void * memcpy ( void * destination, const void * source, size_t num );

我们要注意,这里的num是以字节为单位的,而不是元素个数,并且由于这里我们不知道memmove所移动的内容是什么数据类型,所以移动的目的和源头都用void来定义,由于memmove函数还需有返回目的的起始地址,所以函数类型定义为void**。

下面我们就可以对memmove函数进行模拟实现

我们定义此模拟实现函数为my_memmove

我们定义数组

arr[]={1,2,3,4,5,6,7}

我们想要将数组中数字3,4,5放入1,2,3的位置中,也就是说src中的内容从前向后移动到det中,反之,如果采用从后向前将不会达到我们想要的下图的数组,移动后的数组内容如下图所示

我们将数组移动的内容进行分析,此时det在src的前面,我们可以先将数字3放入arr[0],然后一次放入4,5

下面来看另外一种情况,就是如果det在src的后面呢,该如何移动呢

这个时候我们就会发现从前向后的方法并不适用与这种情况了,我们可以采用从后向前的方式,若依旧采用从前向后的方式的话,会是这种效果

这个时候我们就可以开始构思函数了

由于函数最终需要返回det的起始地址,所以我们定义一个void* ret=det放入函数中,并且采用断言保证不为空指针

void my_memmove(void* det, void* src, size_t size)
{ 
        assert(det && src);
        void* ret = det;
}

接下来分析当det在src前面是的移动方式

由于不知道数据的类型,并且size的单位是字节,但是当数据的类型是int的时候,循环进行是该如何移动呢,我们就可以将det的指针类型强制转化为char*指针,就可以进行字节“++”操作了

if (det < src)//从前往后移动
  {
    int i = 0;
    for (i = 0; i < size; i++)
    {
      *(char*)det = *(char*)src;//强制类型转换
      arr1 = (char*)det + 1;
      arr2 = (char*)src + 1;
    }

反之,我们就写出det在src之后的部分

while (size--)
    {
      *((char*)det + size) = *((char*)src + size);
    }

到这里,memmove的模拟实现就完成了,我们还要记得返回ret,也就是det的起始地址

完整函数代码如下

void my_memmove(void* det, void* src, size_t size)
{
  assert(det && src);
  void* ret = det;
  if (det < src)//从前往后移动
  {
    int i = 0;
    for (i = 0; i < size; i++)
    {
      *(char*)det = *(char*)src;
      arr1 = (char*)det + 1;
      arr2 = (char*)src + 1;
    }
  } 
  else
  {
    while (size--)
    {
      *((char*)det + size) = *((char*)src + size);
    }
  }
  return ret;
}

memcpy函数

相对于memmove函数,memcpy的功能就没有怎么完整了,memmove和memcpy的差别就是memmove函数处理的源内存块和⽬标内存块是可以重叠的,所以,如果源空间和⽬标空间出现重叠,就得使⽤memmove函数处理。但是,有一些编译器的memcpy也可以处理重叠的的情况,就比如vs。

memcpy的模拟实现和memmove的差别不大

代码如下

void * memcpy ( void * det, const void * src, size_t size)
{
 void * ret = det;
assert(arr1 && arr2);
 while (size--) {
 *(char *)dst = *(char *)src;
 dst = (char *)dst + 1;
 src = (char *)src + 1;
 }
 return(ret);
}

大家可以发现,memcpy函数的模拟实现就是memmove函数模拟实现的一部分,就是只采用了从前向后的方式进行内存更改,所以这里我就不做过多的解释了,大家自行理解。

好了,今天的分享就到这里了!

相关文章
|
6月前
|
存储 编译器 C++
13函数
13函数
24 0
|
2月前
|
存储 Python
有效的函数(一)
有效的函数(一)
|
5月前
|
算法 程序员 编译器
函数(2)
函数(2)
21 0
|
6月前
函数(二)
函数(二)
24 0
|
6月前
|
前端开发 JavaScript
Less的函数的介绍
Less的函数的介绍
56 0
|
11月前
|
存储 C语言
对函数的剖析二
对函数的剖析二
52 0
|
11月前
|
存储 编译器
函数(下)
函数(下)
81 0
|
程序员 C语言 C++
函函函函函函函函函函函数——one
函函函函函函函函函函函数——one
86 0
|
Python
什么是函数
什么是函数
95 0