Memset memcpy Strcpy 函数使用探究

举报
CodeAllen 发表于 2021/10/30 00:53:24 2021/10/30
【摘要】 做串口通信时用到的函数,这篇不错,整理下使用 一个小例子: *memcpy(txbuf,“添加的内容\n”,100);HAL_UART_Transmit(&husartx,txbuf,strlen((char )txbuf),1000); 原网址:http://bbs.elecfans.com/forum.php...

做串口通信时用到的函数,这篇不错,整理下使用

一个小例子:


  
  1. *memcpy(txbuf,“添加的内容\n”,100);
  2. HAL_UART_Transmit(&husartx,txbuf,strlen((char )txbuf),1000);

原网址:http://bbs.elecfans.com/forum.php?mod=viewthread&tid=466498&extra=

 

(1) Memset


  
  1. 原型: extern void *memset(void *buffer, int c, int count);
  2. 用法: #include <string.h>
  3. 功能: 把buffer所指内存区域的前count个字节设置成字符 c。
  4. 说明: 返回指向buffer的指针。用来对一段内存空间全部设置为某个字符
  5. 例如:
  6. char a[10];
  7. memset(a, '\0', sizeof(a));
  8. memset可以方便的清空一个结构类型的变量或数组。
  9. 如:struct _test{ char s[10];
  10. int x;
  11. int y;
  12. };
  13. 变量 struct _test st;
  14. (1)一般清空st的方法如下:
  15. st.s[0] = '\0'; st.x =0; st.y =0;
  16. (2) 用memset方法如下:
  17. memset(&st,0,sizeof(struct _test));
  18. 数组: struct _test st[10];
  19. memset(st,0,sizeof(struct _test)*10); //清空方法
  20. //memset 源码的实现 C语言
  21. #include <mem.h>
  22. void* memset(void* s, int c, size_t n)
  23. {
  24. unsigned char* p = (unsigned char*) s;
  25. while (n > 0)
  26. {
  27. *p++ = (unsigned char) c;
  28. --n;
  29. }
  30. return s;
  31. }

(2)memcpy


  
  1. 原型:extern void *memcpy(void*dest,void*src,unsignedintcount); 用法: #include <string.h>
  2. 功能: 由src所指内存区域复制count个字节到dest所指内存区域。
  3. 说明: src和dest所指内存区域不能重叠,函数返回指向dest的指针.可以拿它拷贝任何数据类型的对象。
  4. 例如: char a[10],b[5];
  5. memcpy(b, a, sizeof(b)); /*注意如果用sizeof(a),会造成b的内存地址溢出*/

(3) Strcpy


  
  1. 原型: extern char *strcpy(char *dest,char *src);
  2. 用法: #include <string.h>
  3. 功能: 把src所指由NULL结束的字符串复制到dest所指的数组中。
  4. 说明: src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳 src的字符串.返回指向dest的指针。
  5. 例如: char a[100],b[50];
  6. strcpy(a,b);
  7. 如用 strcpy(b,a);
  8. 要注意a中的字符串长度(第一个‘\0’之前)是否超过50位,如超过,则会造成b的内存地址溢出。
  9. 假如有如下代码,请问输出为多少?
  10. #include "stdio.h"
  11. main()
  12. { char dest[3];
  13. char str[6]="Hello";
  14. strcpy(dest,str);
  15. printf("%s\n",dest);
  16. }
  17. 编译输出如下结果:
  18. Hello //没有输出乱码,有点怪怪的为什么?
  19. 分析:
  20. 1>str中字符串的长度大于dest 的内存长度3.为什么str字符串还能完拷贝到dest 中呢?
  21. 来看看 strcpy的 源代码实现:
  22. char *strcpy(char *strDest,const char *strSrc)
  23. {
  24. assert((strDest!=NULL)&&(strSrc !=NULL)) //判断指针是否合法,即分配内存,指向某块确定区域
  25. char *address = strDest; //记住目标地址的起始值
  26. while((*strDest++ = *strSrc++)!='\0') //先拷贝,后判断,这样就不用在拷贝完了后,再加一句
  27. NULL; // *strDest = '\0'; -->即加一个结束符.因为字符串结束已拷贝了.
  28. return address; //返回目标首地址的值。
  29. }
  30. //从上面的代码可以看出,strcpy函数,假定strDest的内存空间是足够可以放下strSrc的内容的.
  31. //也就是说使用者,在使用strcpy函数时,应使 (strDest内存空间)>= (strSrc内存空间)
  32. // 在调用 strcpy(dest,str); 时,while((*strDest++ = *strSrc++)!='\0') 没有判断strDest的内存是否够,而是将srtSrc的内容直接拷贝到strDest,当拷到'\0'就结束.
  33. //因此在使用printf("%s\n",dest); 时 输出遇到'\0'时停此输出.所以会输出: Hello

(4) 三者区别

  1.   memset   主要应用是初始化某个内存空间。                  
  2.  memcpy   是用于copy源空间的数据到目的空间中。                  
  3.  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);

 

文章来源: allen5g.blog.csdn.net,作者:CodeAllen的博客,版权归原作者所有,如需转载,请联系作者。

原文链接:allen5g.blog.csdn.net/article/details/88962411

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。