• 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 个字节,不会因为遇到“”而结束。

    【返回值】返回指向 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, '', 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;
    }
  • 相关阅读:
    在Azure虚拟机上安装SQL server
    Azure的负载均衡机制
    如何在ARM中创建Express Route
    如何将已部署在ASM的资源迁移到ARM中
    Azure上的那些IP
    使用mysqlslap对mysql进行压测,观察Azure虚拟机cpu使用率
    在Azure虚拟机上安装VNC
    DataGridView中实现checkbox全选的自定义控件
    jquery checkbox 实现单选
    如何通过Azure Service Management REST API管理Azure服务
  • 原文地址:https://www.cnblogs.com/shihaochangeworld/p/5500772.html
Copyright © 2020-2023  润新知