zoukankan      html  css  js  c++  java
  • 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);

  • 相关阅读:
    主机的IOPS需求转换成硬盘实际IOPS负载
    IT安全运维职责
    IT应用运维职责
    存储RAID 选择策略
    交换机接口下错包计数,哪些是属于物理链路(包括本端设备和对端设备硬件问题)引起的
    华为交换机SNMP配置
    c# 位与运算符&简单实现复选框功能【实际应用】
    centos7 安装谷歌浏览器教程
    centos7下 Consul安装
    .netcore3.1 获取请求头header中认证信息并调用其它接口
  • 原文地址:https://www.cnblogs.com/wenxp2006/p/2500856.html
Copyright © 2011-2022 走看看