Memset、Memcpy、Strcpy 的作用和區別(轉)


(1) Memset
  原型:   extern void *memset(void *buffer, int c, int count);              
  用法:  #include <string.h>           

   功能: 把buffer所指內存區域的前count個字節設置成字符 c。           
  說明: 返回指向buffer的指針。用來對一段內存空間全部設置爲某個字符
              例如:     
                    char a[10];                        
                    memset(a, '\0', sizeof(a));               
        memset可以方便的清空一個結構類型的變量或數組。               
             如:struct    _test{  char s[10];      
                                          int x;      
                                          int y;
                                        };        
    變量     struct _test    st;              
(1)一般清空st的方法如下:
st.s[0] = '\0'; st.x =0;   st.y =0;               
(2) 用memset方法如下:               
             memset(&st,0,sizeof(struct _test));         
    數組:  struct _test     st[10];               
  memset(st,0,sizeof(struct _test)*10);  //清空方法
//memset 源碼的實現 C語言
#include <mem.h>
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;
  }



(2)memcpy
原型:extern void *memcpy(void*dest,void*src,unsignedintcount);              用法: #include <string.h>              
功能: 由src所指內存區域複製count個字節到dest所指內存區域。            
說明: src和dest所指內存區域不能重疊,函數返回指向dest的指針.可以拿它拷貝任何數據類型的對象。   
             例如:  char a[10],b[5];              
                        memcpy(b, a, sizeof(b));             /*注意如果用sizeof(a),會造成b的內存地址溢出*/
(3) 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的內存地址溢出。
    假如有如下代碼,請問輸出爲多少?
            #include "stdio.h"
            main()
                {  char dest[3];
                    char str[6]="Hello";

               strcpy(dest,str);
                    printf("%s\n",dest);

              }
        編譯輸出如下結果:
        Hello                  //沒有輸出亂碼,有點怪怪的爲什麼?
       分析:
             1>str中字符串的長度大於dest 的內存長度3.爲什麼str字符串還能完拷貝到dest 中呢?
      來看看 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;      //返回目標首地址的值。            
               }

        //從上面的代碼可以看出,strcpy函數,假定strDest的內存空間是足夠可以放下strSrc的內容的.
        //也就是說使用者,在使用strcpy函數時,應使 (strDest內存空間)>=  (strSrc內存空間)     
        // 在調用   strcpy(dest,str);  時,while((*strDest++   =   *strSrc++)!='\0')   沒有判斷strDest的內存是否夠,而是將srtSrc的內容直接拷貝到strDest,當拷到'\0'就結束.
        //因此在使用printf("%s\n",dest);  時 輸出遇到'\0'時停此輸出.所以會輸出: Hello

    (4) 三者區別                    
           memset   主要應用是初始化某個內存空間。                  
           memcpy   是用於copy源空間的數據到目的空間中。                  
           strcpy   用於字符串copy,遇到‘\0’,將結束。                  
如果理解了這些,就能知道它們的區別:                 
       例如初始化某塊空間的時候,用到memcpy,那麼就顯得笨拙                 
    int    m[100]                     
memset((void*)m,0x00,sizeof(int*100);             //Ok!                     
memcpy((void*)m,"\0\0\0\0....",sizeof(int)*100);    //Not Ok
一.函數原型   
    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 用來對一段內存空間全部設置爲某個字符,一般用於在對定義的字符串初始化爲' '或者'\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);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章