升级版memcpy————>memmove函数

前言:

书接上回,咱们继续来讲解字符串函数和内存函数。本期要讲的是memmove函数,此函数可比上一节的memcpy函数好用多了!!!话不多说,开讲!


什么是memmove函数?

通过查阅MSDN(C语言万法宝典!),我们可以看到memmove的返回值类型,参数类型和memcpy函数简直一模一样!头文件是string.h

通过字面意思可以得知memmove即memory move,翻译过来就是内存移动。那显而易见,memmove就是把源头内存块count个字节的内容移动到目标内存块。

注意:

src参数使用了const修饰,那么意味着不可通过src去改变src所指向的内容。

那么此处的移动并非是将源头拿到目标之后,源头就没了。而是将源头内存块的内容拷贝了一份然后移动到目标内存块。

见实例:

此程序的数组arr1即为目标内存块,数组arr2即为源头内存块。显而易见,arr1被改变,但arr2仍然是原来的数组。


memmove函数如何使用?

memove的使用方法和memcpy函数使用方法一模一样,这里就不多说了。不懂的去看上一节。

memmove函数和memcpy函数的区别在哪?

来看实例:

此程序中,我们用自己定义的memcpy函数来将arr1数组内存块的20个字节

拷贝到arr1+2所指向的内存块中,理想打印结果应该是1 2 1 2 3 4 5 8 9 10

但实际结果却成了 1 2 1 2 1 2 1 8 9 10。

原因分析:

这里不用memcpy函数的原因是经过实验,在VS编译器中memcpy会正常拷贝成

1 2 1 2 3 4 5 8 9 10(但是其他编译器就不一定了),所以用自定义的my_memcpy函数来举例。那么为了解决在内存块重叠情况下的拷贝时,memmove函数就派上了用场。

接下来我们同样场景下,看看使用memmove函数拷贝会是怎样的情况?

我们发现使用memmove就正常的进行了拷贝。那么为什么memmove函数可以正常拷贝呢?

这就取决于memmove相对于memcpy的一个优化。

因为总有特殊情况下,源头内存块和目标内存内存块会重叠,在这些内存重叠的情况下,有的时候从前往后拷贝就可以正常拷贝,有的时候从后往前就可以正常拷贝,还有的时候都可以正常拷贝。

那么接下来我就带大家分析一下什么时候该用什么样的顺序拷贝:

值得一提的是:

当内存重叠时,有时候src指向的内容被改变了,这并非是定义错误了。而是src和dest指向的内存块重叠时,通过dest改变了那部分内容,而非通过src改变。所以还是没问题的。


那么学会区分拷贝顺序之后,那么我们就可以轻松的自定义出my_memmove函数了!

自定义memmove函数

其中从前往后拷贝的定义和memcpy函数是一样的,从后往前拷贝主要是num--来控制拷贝的次数。

void* my_memmove(void* dest, const void* src, size_t num)
{
    assert(dest && src);
    void* ret = dest;
    if (dest < src)//从前向后拷贝
    {
        while (num--)
        {
            *(char*)dest = *(char*)src;
            dest = (char*)dest + 1;
            src = (char*)src + 1;
        }
    }
    else//从后向前拷贝
    {
        while (num--)
        {
            //*(char*)dest = *(char*)src;
            //dest = (char*)dest - 1;
            //src = (char*)src - 1;
            *((char*)dest + num) = *((char*)src + num);//这样更简洁 
        }
    }
    return ret;
}
int main()
{
    int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
    int arr2[8] = { 0 };
    memmove(arr1 + 2, arr1, 20);
    for (int i = 0; i < 10; i++)
    {
        printf("%d ", arr1[i]);//1 2 1 2 3 4 5 8 9 10 
    }
    return 0;
}

自定义函数代码自取。


结语:

到这里,此章关于memmove函数的的内容就结束啦,以后遇到memcpy无法解决的地方就可以用memmove喽。喜欢的就点个赞吧!期待我们的下一次相遇!

最后还是那句老话:路漫漫其修远兮,吾将上下而求索!!!

  • 18
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值