C標準ライブラリ(7)——“string.h”の中の関数の実現memcmpに入って、memcpy、memmove、memset

19874 ワード

私の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の2つの関数の違いについて』
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 }

 
完了