zoukankan      html  css  js  c++  java
  • 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 == 0return 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;
    }




  • 相关阅读:
    Python笔记_第一篇_面向过程_第一部分_7.文件的操作(.txt)
    Python笔记_第一篇_面向过程_第一部分_6.语句的嵌套
    Python笔记_第一篇_面向过程_第一部分_6.其他控制语句(with...as等)
    Python笔记_第一篇_面向过程第一部分_6.循环控制语句(while 和 for)_
    Python笔记_第一篇_面向过程_第一部分_6.条件控制语句(if)
    matplot 代码实例
    python下的MySQLdb使用
    vim操作笔记
    使用k-近邻算法改进约会网站的配对效果
    python 读取文本
  • 原文地址:https://www.cnblogs.com/no7dw/p/1929930.html
Copyright © 2011-2022 走看看