• 走进C标准库(7)——"string.h"中函数的实现memcmp,memcpy,memmove,memset


    我的memcmp:

     1 int memcmp(void *buf1, void *buf2, unsigned int count){
     2     int reval;
     3     while(count && !(reval = (*(unsigned char *)buf1) - (*(unsigned char *)buf2)))
     4     {
     5         buf1 = (unsigned char *)buf1 + 1;
     6         buf2 = (unsigned char *)buf2 + 1;
     7         --count;
     8     }
     9     return reval;
    10 }

    MS VC:

    int __cdecl memcmp (
            const void * buf1,
            const void * buf2,
            size_t count
            )
    {
            if (!count)
                    return(0);
    
            while ( --count && *(char *)buf1 == *(char *)buf2 ) {
                    buf1 = (char *)buf1 + 1;
                    buf2 = (char *)buf2 + 1;
            }
    
            return( *((unsigned char *)buf1) - *((unsigned char *)buf2) );
    }

    应该使用const void *buf为宜,不改变该块内存的内容,最终使用unsigned char *进行运算,保证运算结果的符号正确。

    我的memcpy:

    1 void *memcpy(void *dest, const void *src, unsigned int count){
    2     void *reval = dest;
    3     while(count--){
    4          (*(unsigned char *)dest++) = (*(unsigned char *)src++);
    5     }
    6     return reval;
    7 }

    MSVC:

     1 void * __cdecl memcpy (
     2         void * dst,
     3         const void * src,
     4         size_t count
     5         )
     6 {
     7         void * ret = dst;
     8 
     9 #if defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC)
    10         {
    11         extern void RtlMoveMemory( void *, const void *, size_t count );
    12 
    13         RtlMoveMemory( dst, src, count );
    14         }
    15 #else  /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
    16         /*
    17          * copy from lower addresses to higher addresses
    18          */
    19         while (count--) {
    20                 *(char *)dst = *(char *)src;
    21                 dst = (char *)dst + 1;
    22                 src = (char *)src + 1;
    23         }
    24 #endif  /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
    25 
    26         return(ret);
    27 }

    我的memmove:

     1 void *memmove(void *dest, const void *src, unsigned int count){
     2     void *reval = dest;
     3     int overlap = ((unsigned char *)src < (unsigned char *)dest && ((unsigned char *)src + count) > dest);
     4     while(count--){
     5         if(overlap)//src is in front of dest and overlap. copy direction is from endIndex to beginIndex
     6               (*((unsigned char *)dest + count)) = (*((unsigned char *)src + count));
     7         else
     8             (*(unsigned char *)dest++) = (*(unsigned char *)src++);
     9     }
    10     return reval;
    11 }

    MSVC:

     1 void * __cdecl memmove (
     2         void * dst,
     3         const void * src,
     4         size_t count
     5         )
     6 {
     7         void * ret = dst;
     8 
     9 #if defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC)
    10         {
    11         extern void RtlMoveMemory( void *, const void *, size_t count );
    12 
    13         RtlMoveMemory( dst, src, count );
    14         }
    15 #else  /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
    16         if (dst <= src || (char *)dst >= ((char *)src + count)) {
    17                 /*
    18                  * Non-Overlapping Buffers
    19                  * copy from lower addresses to higher addresses
    20                  */
    21                 while (count--) {
    22                         *(char *)dst = *(char *)src;
    23                         dst = (char *)dst + 1;
    24                         src = (char *)src + 1;
    25                 }
    26         }
    27         else {
    28                 /*
    29                  * Overlapping Buffers
    30                  * copy from higher addresses to lower addresses
    31                  */
    32                 dst = (char *)dst + count - 1;
    33                 src = (char *)src + count - 1;
    34 
    35                 while (count--) {
    36                         *(char *)dst = *(char *)src;
    37                         dst = (char *)dst - 1;
    38                         src = (char *)src - 1;
    39                 }
    40         }
    41 #endif  /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
    42 
    43         return(ret);
    44 }

    关于memcpy和memmove的区别,memcpy不考虑内存区域重叠的情况而memmove保证内存区域重叠也能正常复制成功。

    有时候我们的memcpy也可能在内存重叠的情况下正常使用,这取决于它的实现,不具有普遍性,C语言标准中未对其有这种要求。

    参考资料:

    《关于memcpy和memmove两函数的区别》

    http://blog.csdn.net/caowei840701/article/details/8491836

    《memcpy() vs memmove()》  

    http://stackoverflow.com/questions/4415910/memcpy-vs-memmove

    我的memset:

    1 void *memset(void *buffer, int c, int count){
    2     void *reval = buffer;
    3     while(count--){
    4         (*(unsigned char *)buffer++) = (unsigned char)c;
    5     }
    6     return reval;
    7 }

    MSVC:

     1 void * __cdecl memset (
     2         void *dst,
     3         int val,
     4         size_t count
     5         )
     6 {
     7         void *start = dst;
     8 
     9 #if defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC)
    10         {
    11         extern void RtlFillMemory( void *, size_t count, char );
    12 
    13         RtlFillMemory( dst, count, (char)val );
    14         }
    15 #else  /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
    16         while (count--) {
    17                 *(char *)dst = (char)val;
    18                 dst = (char *)dst + 1;
    19         }
    20 #endif  /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
    21 
    22         return(start);
    23 }

  • 相关阅读:
    ASIHTTPRequest类库简介和使用说明
    UIDatePickerView实现时间滚动轮播效果
    UIPickerView选择控件实现选择轮播效果(转轮效果)
    懒加载三大优势
    UIView的自适应高度 (图像,文字)
    正则表达式校验yyyymmdd
    Java时间日期格式转换 转自:http://www.cnblogs.com/edwardlauxh/archive/2010/03/21/1918615.html
    java.sql.SQLException: ORA-00911: 无效字符 解决方法 引自: http://blog.csdn.net/yangzhijun_cau/article/details/6064956
    跨域访问
    maven + eclipse + tomcat热部署 引自:http://jingpin.jikexueyuan.com/article/23068.html
  • 原文地址:https://www.cnblogs.com/shijiezhenmei/p/3701551.html
Copyright © 2020-2023  润新知