mem 族函数的实现

1.void * memcpy ( void * dest, const void * src, size_t num );

头文件:#include <string.h>
memcpy() 用来复制内存,memcpy() 会复制 src 所指的内存内容的前 num 个字节到 dest 所指的内存地址上。
memcpy() 并不关心被复制的数据类型,只是逐字节地进行复制,这给函数的使用带来了很大的灵活性,可以面向任何数据类型进行复制。
需要注意的是:

  • dest 指针要分配足够的空间,也即大于等于 num 字节的空间。如果没有分配空间,会出现断错误。
  • dest 和 src 所指的内存空间不能重叠(如果发生了重叠,使用 memmove() 会更加安全)。
     strcpy() 不同的是,memcpy() 会完整的复制 num 个字节,不会因为遇到“\0”而结束。

【返回值】返回指向 dest 的指针。注意返回的指针类型是 void,使用时一般要进行强制类型转换。

 

 

void* Memcpy(void* dst,const void* src, int n)
{
    if (dst == NULL || src == NULL)
    {
        return dst;
    }
    void* result = dst;
    while (n--)
    {
        *(char*)dst = *(char*)src;
        dst = (char*)dst + 1;
        src = (char*)src + 1;
    }
    return result;
}


 

 

 

2.void* memmove(void* dst, const void* src, size_t n) 

但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开销。

memmove的处理措施:

(1)当源内存的首地址等于目标内存的首地址时,不进行任何拷贝

(2)当源内存的首地址大于目标内存的首地址时,实行正向拷贝

(3)当源内存的首地址小于目标内存的首地址时,实行反向拷贝

void* Memmove(void* dst,const void* src, int n)
{
    if (dst == NULL || src == NULL || dst == src)   //不用拷贝
    {
        return dst;
    }
    char* m_dst = (char*)dst;
    char* m_src = (char*)src;
    if (m_dst > m_src && m_dst < m_src + n) //反向拷贝
    {
        m_dst = m_dst + n - 1;
        m_src = m_src + n - 1;
        while (n--)
        {
            *m_dst-- = *m_src--;
        }            
    }
    else  //正向拷贝
    {
        while (n--)
        {
            *m_dst++ = *m_src++;
        }        
    }
    return dst;
}

 

3.memcmp

头文件:#include <string.h>
定义函数:int memcmp (const void *s1, const void *s2, size_t n);
函数说明:memcmp()用来比较s1 和s2 所指的内存区间前n 个字符。
字符串大小的比较是以ASCII 码表上的顺序来决定,次顺序亦为字符的值。memcmp()首先将s1 第一个字符值减去s2 第一个字符的值,若差为0 则再继续比较下个字符,若差值不为0 则将差值返回。例如,字符串"Ac"和"ba"比较则会返回字符'A'(65)和'b'(98)的差值(-33)。
返回值:若参数s1 和s2 所指的内存内容都完全相同则返回0 值。s1 若大于s2 则返回大于0 的值。s1 若小于s2 则返回小于0 的值。

int Memcmp(const void *s1, const void *s2, size_t n)
{
    assert(s1 && s2);
    char* m_s1 = (char*)s1;
    char* m_s2 = (char*)s2;
    while (n--)
    {
        if (*m_s1 - *m_s2)
        {
            return *m_s1 - *m_s2;
        }
        else
        {
            m_s1++;
            m_s2++;
        }
    }
    return 0;
}

 

 

4.memset

memset() 函数用来将指定内存的前n个字节设置为特定的值,其原型为:
    void * memset( void * ptr, int value, size_t num );

参数说明:

  • ptr 为要操作的内存的指针。
  • value 为要设置的值。你既可以向 value 传递 int 类型的值,也可以传递 char 类型的值,int 和 char 可以根据 ASCII 码相互转换。
  • num 为 ptr 的前 num 个字节,size_t 就是unsigned int。


【函数说明】memset() 会将 ptr 所指的内存区域的前 num 个字节的值都设置为 value,然后返回指向 ptr 的指针。

memset() 可以将一段内存空间全部设置为特定的值,所以经常用来初始化字符数组。例如:

  1. char str[20];
  2. memset(str, '\0', sizeof(str)-1);


【返回值】返回指向 ptr 的指针。

注意:参数 value 虽声明为 int,但必须是 unsigned char,所以范围在0 到255 之间。

void * Memset(void * ptr, int value, size_t num)
{
    assert(ptr);
    char* m_ptr = (char*)ptr;
    while (num--)
    {
        *(m_ptr++) = value;
    }
    return ptr;
}

 

posted @ 2016-05-17 11:07  _in_the_way  阅读(629)  评论(0编辑  收藏  举报