【C语言】带你手撕字符函数和字符串函数(3)(内含memcpy、memmove、memcmp函数 )

文章介绍了C语言中三个重要的内存操作函数:memcpy用于无重叠区域的数据复制,memmove处理可能重叠的内存块,memcmp用于比较两块内存区域。文章详细阐述了这些函数的定义、使用场景,并提供了模拟实现的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

往期回顾:

【C语言】带你手撕字符函数和字符串函数(1)(内含部分库函数模拟实现)

【C语言】带你手撕字符函数和字符串函数(2)(内含字符串查找函数、字符分类函数等)


本篇文章是字符函数系列的最终章,篇幅不会很长,我们将一起来学习三个常用的内存操作函数:memcpy、memmove和memcmp函数。

话不多说直接上货


1 memcpy

1.1 memcpy的定义

memcpy是用来将源空间中指定大小字节的数据复制到目标空间的函数。定义如下:

  • 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。(注意:这里的num是字节的参数,而不是元素个数的参数)

  • 这个函数遇到'\0'的时候不会停下来

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

为什么在这里,参数destination和source的返回类型是void*类型呢?

这样做可以使这个函数变成通用函数。设计者在设计函数时,并不知道在将来使用这个函数的人会用其复制哪种数据类型,因此在这里统一设置成void*类型。

void*类型也被称为通用类型指针,它的特点是可以接收任意类型数据的地址

1.2 memcpy的模拟实现

既然memcpy是逐个字节拷贝数据,且接受的参数是void*类型,那我们就可以将参数指针通过强制类型转换成char*类型。由于char类型占用大小是一个字节,那么char*指针每次加1就能跳过一个字节。

void *my_memcpy(void* dest, const void* src, size_t size)
{
    void* ret = dest;
    while (size--)
    {
        *(char*)dest = *(char*)src;
        dest = (char*)dest + 1;
        src = (char*)src + 1;
    }
    return ret;
}

2 memmove

2.1 memmove的定义

  • memmove其实跟memcpy很像,区别在于memmove处理的源内存块和目标内存块是可以重叠的,而memcpy则不行。

因此,如果遇到源内存块和目标内存块重叠的情况,就用memmove函数处理

2.2 memmove函数的模拟实现

memmove函数模拟的实现较为复杂

void* my_memmove(void* dest, const void* src, size_t size)
{
    void* ret = dest;
    if (dest <= src || (char*)dest >= (char*)src + size)
    {
        while (size--)
        {
            *(char*)dest = *(char*)src;
            dest = (char*)dest + 1;
            src = (char*)src + 1;
        }
    }
    else
    {
        dest = (char*)dest + size - 1;
        src = (char*)src + size - 1;
        while (size--)
        {
            *(char*)dest = *(char*)src;
            dest = (char*)dest - 1;
            src = (char*)src - 1;
        }
    }
    return ret;
}

3 memcmp

3.1 memcmp的定义

  • 函数memcmp比较从ptr1和ptr2两个指针开始的num个字节

  • 返回值如下:

其实memcmp的返回跟strcmp非常相似,只是memcmp不仅仅可以用来比较字符串大小,使用更加灵活

3.2 memcmp的模拟实现

此处可以类比strcmp的模拟实现,稍作修改即可写出memcmp

int my_memcmp(const void* ptr1, const void* ptr2, size_t num)
{
    assert(ptr1 && ptr2);
    while (num--)
    {
        if (*(char*)ptr1 == *(char*)ptr2)
        {
            ((char*)ptr1)++;
            ((char*)ptr2)++;
        }
        else
            return (*(char*)ptr1 - *(char*)ptr2);
    }
    return 0;
}

至此,字符函数和字符串函数系列结束

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值