Memset、Memcpy、Strcpy 的作用和区别(来源于网络并整理)

来源:互联网 发布:js 选项卡 编辑:程序博客网 时间:2024/06/08 16:19

一.函数原型   
    strcpy    extern char *strcpy(char *dest,char *src);   
    #include <string.h>   
   功能:把src所指由NULL结束的字符串复制到dest所指的数组中   
   说明:  src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。    返回指向dest的指针  
    memcpy   extern void *memcpy(void *dest,void *src,unsigned int count); 
    #include <string.h>   
    功能:由src所指内存区域复制count个字符串到dest所指内存区域.   
    说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针.      
    memset    extern void *memset(void *buffer,int c,int count);   
    #include <string.h>   
    功能:把buffer所指内存区域的前count个字节设置成字符c   
   说明:返回指向buffer的指针.
二.源代码实现
//memset 源码的实现 C语言
   void* memset(void* s, int c, size_t n)
   {
     unsigned char* p = (unsigned char*) s;
     while (n > 0)
       {
               *p++ = (unsigned char) c;
                --n;
       }
      return s;
   }
// strcpy的 源代码实现:
   char   *strcpy(char   *strDest,const   char   *strSrc)  
   {  
        assert((strDest!=NULL)&&(strSrc   !=NULL))   //判断指针是否合法,即分配内存,指向某块确定区域
        char   *address   =   strDest;               //记住目标地址的起始值
        while((*strDest++   =   *strSrc++)!='\0')   //先拷贝,后判断,这样就不用在拷贝完了后,再加一句
              NULL;                   // *strDest = '\0'; -->即加一个结束符.因为字符串结束已拷贝了.
              return   address;      //返回目标首地址的值。            
   }
//memcpy的源代码实现
   void* memcpy(void* pvTo,const void* pvFrom,size_t size)
   {
         assert((pvTo!=NULL)&&(pvFrom!=NULL));
         unsigned char* pbTo=(unsigned char*)pvTo;
         unsigned char* pbFrom=(unsigned char*)pvFrom;
         while(size-->0)
         {
            *pbTo++=*pbFrom++;
          }
          return pvTo;
      }

三.区别  

memset 用来对一段内存空间全部设置为某个字符,一般用于在对定义的字符串初始化为' '或者'\0';    
           例: char a[100];           memset(a,'\0',sizeof(a));       
memcpy 是用来做内存拷贝,可以用来拷贝任何数据类型的对象,可以指定拷贝的数据长度;   
             例:       char a[100],b[50];           
                       memcpy(b,a,sizeof(b));   
   //注意:如果使用sizeof(a),会造成内存溢出           
   mem是一段内存,他的长度,必须自己记住.memcpy是见着什么拷贝什么。        
strcpy 就只能拷贝字符串,它遇到'\0'就结束拷贝;     
            例:char a[100],b[50];               strcpy(a,b);             
            如用strcpy(b,a)要注意a中的字符串长度(第一个'\0'之前) 是否超过50,如果超过,则会造成b的   内存溢出.
      它是不会拷贝'\0'的,所以一般还有加一个语句:               *a='\0';  
四.使用技巧 

  memset 可以方便的清空一个数据结构的变量或数组.     
        如:         struct sample_struct  { 
                                  char   csName[16];              
                                  int      iSeq;             
                                  int       iType;       
                                    };       
       对于变量       
        struct sample_struct   stTest;       
                一般情况下,初始化stTest的方法:        
                         stTest.csName[0]='\0';        
                         stTest.iSeq=0;        
                         stTest.iType=0;    
         而用memset:       
                 memset(&stTest,0,sizeof(struct sample_struct));   
                    如果是数组:    
                     struct sample_struct   TEST[100];    
                     memset(TEST,0,sizeof(struct sample_struct)*100);
五.一个例子
    假如有如下代码,请问输出为多少?会造成什么问题
            #include "stdio.h"
            main()
                {  char dest[3];
                    char str[6]="Hello";
               strcpy(dest,str);
                    printf("%s\n",dest);
              }
        编译输出如下结果:
        Hello                ,会导致内存溢出