实现memcpy( )和memmove( )函数

**

1.实现memcpy()函数

**
memcpy()为字节拷贝函数,他能拷贝任意类型的数组,是根据内存中的二进制码依次进行拷贝的。由于字符串拷贝函数strcpy()的结束标志是0,假如我们现在有int arr1[] = { 4, 2, 3, 4 };int arr2[] = {1,3,4,6}; 利用strcpy((char )arr1, (char )arr2);则输出的不是1,3,4,6 。因为一个整型数字占4个字节,也就是32个比特位,一个字符串占1个字节,8个比特位。strcpy是按照字节依次拷贝的,当遇到‘\0’时结束拷贝。这样1后面的0就会被当作字符串结束标志处理,所以把1拷贝进去后,将不会继续拷贝。我们来看下面的代码验证:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main()
{
    int arr1[] = { 4, 2, 3, 4 };
    int arr2[] = {1,3,4,6};
    strcpy((char *)arr1, (char *)arr2);
    for (int i = 0; i < 4;i++)
    printf("%d ",arr1[i]);
    system("pause");
    return 0;
}

我的结果是:

接下来,我们就来实现memcpy()函数:

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

void * my_memcpy(void *des, const void *src, size_t n)
{
    assert(des);
    assert(src);

    char *pdes = (char *)des;
    char *psrc = (char *)src;
    void *ret = des;

    while (n)
    {
        *pdes++ = *psrc++;
        n--;
    }

    return ret;
}

int main()
{ 
    int des[30] = { 4, 2, 3, 4 };
    int src[] = { 1, 3, 4, 6 };
    int i = 0;

    my_memcpy(des, src,sizeof(src));

    for (i = 0; i < sizeof(src) / sizeof(src[0]);i++)
    {
        printf("%d ", des[i]);
    }

    printf("\n");
    system("pause");
    return 0;
}

这里写图片描述

但是,当我们需要拷贝的字符串有内存重叠的时候,比如源字符串是目标字符串的一部分,则这时候会丢失数据,无法得到正确的结果(如下图所示)。此时,就需要用到memmove()函数进行拷贝。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main()
{ 
    char p[256] = "hello world!";
    memcpy(p, p+5,strlen(p));
    printf("%s\n", p);
    system("pause");
    return 0;
}

这里写图片描述

**

2.实现memmove()函数

**
下面我们来实现自己的memmove()函数:

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>

void *my_memmove(void *des, void *src, size_t count)
{
    assert(des);
    assert(src);

    void *ret = des;
    //从前往后拷贝
    if ((des <= src) || (char *)des >= (char *)src + count)
    {
        while (count--)
        {
            *(char *)des = *(char *)src;
            (char *)des = (char *)des + 1;
            (char *)src = (char *)src + 1;
        }
    }
    else
        //从后往前拷贝
    {
        des = (char *)des + count - 1;
        src = (char *)src + count - 1;
        while (count--)
        {
            *(char *)des = *(char *)src;
            (char *)des = (char *)des - 1;
            (char *)src = (char *)src - 1;
        }
    }

    return ret;
}

int main()
{
    char arr1[30] = "abcdefgh";
    printf("用字符串测试:");
    char *ret1=my_memmove(arr1 + 5, arr1, strlen(arr1) + 1);
    printf("%s\n", ret1);

    int arr2[30] = { 1, 3, 5, 7, 9 };
    printf("\n用整型数组测试:");
    int *ret2 = my_memmove(arr2 + 3, arr2, 5 * sizeof(int));
    int i = 0;
    for (i = 0; i < 5; i++)
    {
        printf("%d ", ret2[i]);
    }

    printf("\n\n");
    system("pause");
    return 0;
}

这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值