memset ,memcpy ,memmove,strcpy 的根本区别 与实现

from:

 

它们用处不同,但大部分情况下可以完成相同的要求。

strcpy

原型:extern char *strcpy(char *dest,char *src);
用法:#include <string.h>
功能:把src所指由NULL结束的字符串复制到dest所指的数组中。
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
    返回指向dest的指针。

例:char a[100],b[50];strcpy(a,b);如用strcpy(b,a),要注意a中的字符串长度(第一个‘\0’之前)是否超过50位,如超过,则会造成b的内存地址溢出。

memcpy
原型:extern void *memcpy(void *dest, void *src, unsigned int count);
用法:#include <string.h>
功能:由src所指内存区域复制count个字节到dest所指内存区域。
说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。可以拿它拷贝任何数据类型的对象。

举例:char a[100],b[50]; memcpy(b, a, sizeof(b));注意如用sizeof(a),会造成b的内存地址溢出。

memset
原型:extern void *memset(void *buffer, int c, int count);
用法:#include <string.h>
功能:把buffer所指内存区域的前count个字节设置成字符c。
说明:返回指向buffer的指针。用来对一段内存空间全部设置为某个字符。

举例:char a[100];memset(a, '\0', sizeof(a));

memset可以方便的清空一个结构类型的变量或数组。

如:
struct  sample_struct
{
char    csName[ 16 ];
int    iSeq;
int    iType;
};

对于变量
struct sample_strcut stTest;

一般情况下,清空stTest的方法:
stTest.csName[ 0 ] = ' \0 ' ;
stTest.iSeq
= 0 ;
stTest.iType
= 0 ;

用memset就非常方便:
memset(&stTest,0,sizeof(struct sample_struct));

如果是数组:
struct sample_struct   TEST[10];

memset(TEST,0,sizeof(struct sample_struct)*10);

对这个问题有疑问,不是对函数的疑问,而是因为没有弄懂mem和str的区别。
mem是一段内存,他的长度,必须你自己记住
str也是一段内存,不过它的长度,你不用记,随时都可以计算出来

所以memcpy需要第三个参数,而strcpy不需要

 

 

memmove

 

原型:extern void *memmove(void *dest, const void *src, unsigned int count);   

用法:#include <string.h>   功能:由src所指内存区域复制count个字节到dest所指内存区域。   

说明:src和dest所指内存区域可以重叠,但复制后dest内容会被更改。函数返回指向dest的指针。

 

 

 实现:

http://www.cnitblog.com/guopingleee/archive/2009/02/15/54581.aspx 

 

strcpy()、memcpy()、memmove()、memset()的实现
 
代码


strcpy(), 字符串拷贝.
char   * strcpy( char   * strDest,  const   char   * strSrc)
{
    assert((strDest
!= NULL)  &&  (strSrc  != NULL));
    
char   * address  =  strDest;    
    
while ( ( * strDest ++   =   *  strSrc ++ !=   ' \0 ' )
       NULL ;
    
return  address ;      
}

代码
memcpy, 拷贝不重叠的内存块
void   * memcpy( void *  pvTo,  void *  pvFrom, size_t size)  // byte是java里的变量类型
{
assert(pvTo 
!=  NULL  &&  pvFrom  !=  NULL);
void *  pbTo  =  ( byte * )pvTo;
void *  pbFrom  =  ( byte * )pvFrom;
/*  内存块重叠吗?如果重叠,就使用memmove  */
assert(pbTo
>= pbFrom + size  ||  pbFrom >= pbTo + size);
while (size --> 0 )
    
* pbTo ++   ==   * pbFrom ++ ;
return  pvTo;
}


代码
void   * MemCopy( void   * dest, const   void   * src,size_t count)
{
    
char   * pDest = static_cast < char   *> (dest);
    
const   char   * pSrc = static_cast < const   char   *> (src);
    
if ( pDest > pSrc  &&  pDest < pSrc + count )
    {
        
for (size_t i = count - 1 ; i <= 0 ++ i)
        {
            pDest[i]
= pSrc[i];
        }
    }
    
else
    {
        
for (size_t i = 0 ; i < count;  ++ i)
        {
             pDest[i]
= pSrc[i];
        }
    }
    
return  pDest;
}


代码

void   * Memmove( void   * Dst,  const   void * Src,size_t count)
{
assert(Dst 
&&  Src);
void *  pDst  =  Dst;
if  (Dst < Src  &&  ( char * )Dst  >  ( char * )Src  +  count)
{
while (count -- )
{
   
* ( char * )Dst  =   * ( char * )Src;
   Dst 
=  ( char * )Dst  +   1 ;
   Src 
=  ( char * )Src  +   1 ;
}
}
else
{
   Dst 
=  ( char * )Dst  +  count  -   1 ;
   Src 
=  ( char * )Src  +  count  -   1 ;
   
while (count -- )
   {
      
* ( char * )Dst  =   * ( char * )Src;
      Dst 
=  ( char * )Dst  - 1  ;
      Src 
=  ( char * )Src  - 1  ;
   }
}
return  pDst;
}


代码

void *  memmove( void   * dest,  const   void   * src,size_t n)
{
    
if  (n  ==   0 return   0 ;
    
if  (dest  ==  NULL)  return   0 ;
    
if  (src  ==  NULL)     return   0 ;
    
char   * psrc  =  ( char * )src;
    
char   * pdest  =  ( char * )dest;
    
if ((dest  <=  psrc)  ||  (pdest  >=  psrc  +  n))  /* 检查是否有重叠问题  */
        {
         
for ( int  i = 0 ; i  <  n; i ++ /* 正向拷贝 */
          {
           
* pdest  =   * psrc;
           psrc
++ ;
           pdest
++ ;
          }
        }
        
else   /* 反向拷贝 */
        {
          psrc 
+=  n;
          pdest 
+=  n;
          
for ( int  i = 0 ;i < n;i ++ )
           {
            psrc
-- ;
            pdest
-- ;
            
* pdest  =   * psrc;
           }
        }
   
return  dest;
}


 


memset:把buffer所指内存区域的前count个字节设置成字符c

void   *  Memset( void *  buffer,  int  c,  int  count)
{
char *  pvTo = ( char * )buffer;
assert(buffer 
!=  NULL);
while (count --> 0 )
* pvTo ++= ( char )c;
return  buffer;
}


 

 

 

 



 

 

 

你可能感兴趣的:(move)