C++面试之strcpy memcpy memmove实现

目录

-strcpy()
- memcpy()
- memmove()

0, strcpy函数

函数原型:

char *strcpy(char *dest, const char *src);

用法:

#include 

功能:把src所指由NULL结束的字符串复制到dest所指的数组中。
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳 src的字符串。
返回:指向dest的指针。
代码实现如下:

char *mystrcpy(char* strDest, const char *strSrc)
{
    assert(nullptr != strDest);
    assert(nullptr != strSrc);

    char *address = strDest;

    int i;
    for (i=0; strSrc[i] != '\0'; i++)
    {
        strDest[i] = strSrc[i];
    }
    strDest[i] = '\0';

    return address;
}

或者更简单的这样实现,先进行赋值再检查

char *mystrcpy(char* strDest, const char *strSrc)
{
    assert(nullptr != strDest);
    assert(nullptr != strSrc);

    char *address = strDest;

    while((*strDest++ = *strSrc++) != '\0');

    return address;
}

延伸考虑内存重叠时, 其实strcpy函数前提便是不发生内存重叠,自己认为上面的实现便可以满足要求,但看到很多博客都在讨论内存重叠的情况,下面也简单记录下

#include 
#include 
#include 
using namespace std;

char *mystrcpy(char* strDest, const char *strSrc)
{
    assert(nullptr != strDest);
    assert(nullptr != strSrc);

    if (strDest == strSrc)
    {
        return strDest;
    }

    char *address = strDest;

    size_t len = strlen(strSrc) + 1;

    // 内存重叠有两种情况:
    //1. strSrc < strDest < strSrc+len 需从高地址向低地址复制
    //2. strDest < strSrc < strDest + len 需从低地址向高地址复制与未重叠情况相同
    if (strDest > strSrc && strDest < strSrc+len)  // 情况1
    {
        strDest += len-1;
        strSrc += len-1;
        for (size_t i= 0; i != len; i++)
        {
            *strDest-- = *strSrc--;
        }
    }
    else //情况2 与 未发生重叠
    {
        for (size_t i= 0; i != len; i++)
        {
            *strDest++ = *strSrc++;
        }

    }

    return address;
}

int main(void)
{
    // 内存重叠 
    char Src[] = "abcde";
    char *Dest2 = Src + 2;
    cout << "srcstr is: " << Src << endl;
    mystrcpy(Dest2, Src);
    cout << "Dest2 is: " << Dest2 << endl;

    //内存不重叠
    char str2[] = "hello world";
    char str3[] = "you are ";
    mystrcpy(str2, str3);
    cout<<"mystrcpy result is :"<return 0;
}

1, memcpy的实现

函数原型:

void *memcpy(void *dest, const void *src, size_t count);

描述:
memcpy()函数从src内存中拷贝n个字节到dest内存区域,但是源和目的的内存区域不能重叠。
返回值:
memcpy()函数返回指向dest的指针。
代码实现如下:

void* mymemcpy(void *dest, const void *src, size_t count)
{
    assert(nullptr != dest);
    assert(nullptr != src);

    char *temp_dest = (char*)dest;
    char *temp_src = (char*)src;
    while(count--) //不需要对是否存在重叠区判断
    {
       *temp_dest++ = *temp_src++;
    }
    return dest;
}

2, memmove() 函数

函数原型:

void * memmove ( void * dest,const void * src,size_t count);

描述:
memmove() 函数从src内存中拷贝n个字节到dest内存区域,但是源和目的的内存可以重叠。
返回值:
memmove函数返回一个指向dest的指针。
代码实现如下:

void* mymemmove(void *dest, const void *src, size_t count)
{
    assert(nullptr != dest);
    assert(nullptr != src);


    // 内存重叠有两种情况:
    //1. src < dest < src+count 需从高地址向低地址复制
    //2. dest < src < dest+count 需从低地址向高地址复制与未重叠情况相同
    if (src < dest && (char*)dest < (char*)src+count) //情况1
    {
        char *temp_dest = (char*)dest + count - 1;
        char *temp_src = (char*)src + count - 1;

        while(count--)
        {
            *temp_dest-- = *temp_src--;
        }
    }
    else //情况2与未发生重叠
    {
        char *temp_dest = (char*)dest;
        char *temp_src = (char*)src;

        while(count--)
        {
            *temp_dest-- = *temp_src--;
        }


    }
    return dest;
}

你可能感兴趣的:(面试,面试,C++)