Memset、Memcpy、Strcpy 的作用和区别(转)

    技术2022-06-23  41

    (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);


    最新回复(0)