走进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 }
完
就算黑夜也有星光。