第一部分  综述

memcpy、memmove、memset、memchr、memcmp都是C语言中的库函数,在头文件string.h中。memcpy和memmove的作用是拷贝一定长度的内存的内容,memset用于缓冲区的填充工作,memchr用于字符的查找工作,memcmp用于比较内存中缓冲区的大小。

第二部分   介绍

1、memcpy和memmove

memcpy()--拷贝内存内容

表头文件:#include<string.h>或#include<cstring>

定义函数:void *memcpy(void *dst,const void *src,size_t n)

函数说明:memcpy用来拷贝src所指的内存内容前n个字节到dst所指的内存地址上。与strcpy不同的是,memcpy会完成的复制n个字节,不会遇到字符串结束'\0'而结束(strncpy待会验证)。

返回值:返回指向dst的指针。

附加说明:指src和dst所指的内存区域不可重叠

重叠实例:

 1 #include<iostream>
 2 #include<string.h>
 3 using namespace std;
 4 int main()
 5 {
 6     int a[10] = {0};
 7     for (int i = 0; i < 10; i++)
 8         a[i] = i;
 9     memcpy(&a[4],a,sizeof(int)*6);
10     //memmove(&a[4], a, sizeof(int) * 6);
11     for (int i = 0; i < 10; i++)
12         cout << a[i];
13     getchar();
14     return 0;
15 }

会输出0123012301,但是vs会输出和memmove一样的结果0123012345,原因是对src进行了保护,不允许更改。

2、memmove()--拷贝内存内容

表头文件:#include<string.h>或#include<cstring>

定义函数:void* memmove(void* dst,const void* src,size_t n)

函数说明:memmove()与memcpy()一样都是用来拷贝src所指的内存前n个字节到dst所指的内存上。

不同的是,当src和dest所指的内存区域重叠时,memmove仍然可以正确的处理,不过执行效率上会比memcpy略慢。

返回值:返回值指向dst的指针。附加说明:指针src和dst所指的内存区域可以重叠。

3、memset()--设置内存内容

表头文件:#include<memory.h>  #include<string.h>

函数说明:memset是C的库函数,将s所指向的某一块内存中的前n个字节全部设置成ch制定的ASCII值,块的大小由第三个参数制定,这个函数通常为新申请的内存做初始化工作。

定义函数:void* memset(void *s,int ch,size_t n)

函数解释:将s中前n个字节用ch替换并返回s。

作用:在一段内存块中填充某个给定的值,他是对较大的结构体或数组进行清零操作的一种最快方法。

返回值:指向s的指针

上面的例子可以改一下

1     int a[10] = {0};
2     memset(a,0,10);

4、memchr()--查找内存内容

表头文件:#include<string.h>

函数说明:从buf所指内存区的前count个字节查找字符ch,当第一次遇到字符ch时停止查找。如果成功,返回指向字符ch的指针;否则返回null

定义函数:extern void* memchr(const void* buf,int ch,size_t count)

代码实现

 1 #include<iostream>
 2 #include<string.h>
 3 using namespace std;
 4 int main()
 5 {
 6     char a[] = "nihao jingliming";
 7     void *p;
 8     p = memchr(a,'j',sizeof(a));
 9     if (p)
10         cout << "has found:" << *((char*)p) << endl;
11     else
12         cout << "not found" << endl;
13     getchar();
14     return 0;
15 }

5、memcmp()--内存比较

表头文件:#include <string.h>

函数原型:int memcmp(const void* buf1,const void* buf2,unsigned int count)

函数描述:比较buf1和buf2的前count个字节

返回值:当buf1<buf2时,返回值<0

    当buf1==buf2时,返回值=0

    当buf1>buf2时,返回值>0

函数说明:该函数是按字节进行比较的

 1 #include<iostream>
 2 #include<string.h>
 3 using namespace std;
 4 int main()
 5 {
 6     char a[] = "nihao jingliming";
 7     char b[] = "nihao xiaoming";
 8     int r=memcmp(a,b,strlen(a));
 9     if (r>0)
10         cout << "a is big" << endl;
11     else if (r < 0)
12         cout << "b is big" << endl;
13     else
14         cout << "same" << endl;
15     getchar();
16     return 0;
17 }

 第三部分  实现

memcpy和memmove

linux内核版

 1 /**
 2  * memcpy - Copy one area of memory to another
 3  * @dest: Where to copy to
 4  * @src: Where to copy from
 5  * @count: The size of the area.
 6  *
 7  * You should not use this function to access IO space, use memcpy_toio()
 8  * or memcpy_fromio() instead.
 9  */
10 void * memcpy(void * dest,const void *src,size_t count)
11 {
12     char *tmp = (char *) dest, *s = (char *) src;
13     while (count--)
14         *tmp++ = *s++;
15     return dest;
16 }

 1 /* Normally compiler builtins are used, but sometimes the compiler calls out
 2    of line code. Based on asm-i386/string.h.
 3  */
 4 #define _STRING_C
 5 #include <linux/string.h>
 6 #undef memmove
 7 void *memmove(void * dest,const void *src,size_t count)
 8 {
 9     if (dest < src) {
10         __inline_memcpy(dest,src,count);
11     } else {
12         char *p = (char *) dest + count;
13         char *s = (char *) src + count;
14         while (count--)
15             *--p = *--s;
16     }
17     return dest;
18 } 

window版

 1 void * __cdecl memcpy (void * dst, const void * src, size_t count)
 2 {
 3         void * ret = dst;
 4
 5         /*
 6          * copy from lower addresses to higher addresses
 7          */
 8         while (count--) {
 9                 *(char *)dst = *(char *)src;
10                 dst = (char *)dst + 1;
11                 src = (char *)src + 1;
12         }
13
14         return(ret);
15 }

 1 void * __cdecl memmove (void * dst, const void * src, size_t count)
 2 {
 3         void * ret = dst;
 4
 5         if (dst <= src || (char *)dst >= ((char *)src + count)) {
 6                 /*
 7                  * Non-Overlapping Buffers
 8                  * copy from lower addresses to higher addresses
 9                  */
10                 while (count--) {
11                         *(char *)dst = *(char *)src;
12                         dst = (char *)dst + 1;
13                         src = (char *)src + 1;
14                 }
15         }
16         else {
17                 /*
18                  * Overlapping Buffers
19                  * copy from higher addresses to lower addresses
20                  */
21                 dst = (char *)dst + count - 1;
22                 src = (char *)src + count - 1;
23
24                 while (count--) {
25                         *(char *)dst = *(char *)src;
26                         dst = (char *)dst - 1;
27                         src = (char *)src - 1;
28                 }
29         }
30
31         return(ret);
32 }

windows写的就是分析的更详细,效率更快。

memset

1 void *(memset) (void *s,int c,size_t n)
2 {
3     const unsigned char uc = c;
4     unsigned char *su;
5     for(su = s;0 < n;++su,--n)
6         *su = uc;
7     return s;
8 }

memchr

 1 void *memchr (const void *ptr, int value, int num)
 2 {
 3 if (ptr == NULL)
 4 {
 5 perror("ptr");
 6 return NULL;
 7 }
 8 char * p = (char *)ptr;
 9 while (num--)
10 {
11 if (*p != (char)value)
12 p++;
13 else
14 return p;
15 }
16
17 return NULL;
18 }

memcmp

 1 /*  因为类型可以为任意,所以形参应为void *
 2  *  相等则返回0,否则不为0
 3  */
 4 int my_memcmp(const void *s1,const void *s2,size_t count)
 5 {
 6     int res = 0;
 7     const unsigned char *p1 =(const unsigned char *)s1;//注意是unsigned char *
 8     const unsigned char *p2 =(const unsigned char *)s2;
 9     for(p1 ,p2;count > 0;p1++,p2++,count--)
10         if((res =*p1 - *p2) != 0)   //不相当则结束比较
11             break;
12     return res;
13 }  

 ststr实现

 1 char* strstr(const char *s1, const char *s2)
 2 {
 3     int n;
 4     if (*s2)
 5     {
 6         while (*s1)
 7         {
 8             for (n=0; *(s1 + n) == *(s2 + n); n++)
 9             {
10                 if (!*(s2 + n + 1))
11                     return (char *)s1;
12             }
13             s1++;
14         }
15         return NULL;
16     }
17     else
18         return (char *)s1;
19 }  

转载于:https://www.cnblogs.com/jingliming/p/4737409.html

memcpy、memmove、memset、memchr、memcmp、strstr详解相关推荐

  1. c语言memset函数用法,C语言memset函数使用方法详解

    C语言memset函数使用方法详解 一.函数原形   void *  memset(void*s, int ch,size_t n) 二.函数作用  将以s内存地址为首的连续n个字节的内容置成ch,一 ...

  2. c语言memset函数作用,C语言memset函数使用方法详解

    C语言memset函数使用方法详解 一.函数原形   void *  memset(void*s,int ch,size_t n) 二.函数作用  将以s内存地址为首的连续n个字节的内容置成ch,一般 ...

  3. memset函数()详解

    在做网络通信编程遇到这个并且理解这个函数,发现这个函数对于较多数据变量同时初始化很有用. 下面就是对于他的一些理解: memset()函数原型是 extern void *memset(void *b ...

  4. memset()函数的用法详解

    前言 最近做题时突然想到用memset给数组的元素赋值100,但是发现结果和想象中的不一样 通过debug看到数组中的元素的值都为1684300900,而明明给它的是100,这是为什么呢,于是查阅了一 ...

  5. memset()函数的使用详解

    memset()是string.h头文件中的函数 作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法 注意: 1.memset函数按字节对内存块进行初始化,所以不 ...

  6. 【C语言】memcmp、memcpy、memmove、memset、memchr函数详解

    目录 一.综述 二.介绍 1.memcmp 2.memcpy 3.memmove 4.memset 5.memchr 一.综述 memcmp.memcpy.memmove.memset.memchr都 ...

  7. C语言常用字符串操作函数大全详解(strstr,strtok,strrchr,strcat,strcmp,strcpy,strerror,strspn,strchr等)

    参考:string.h中常用字符串操作函数说明(strstr,strtok,strrchr,strcat,strcmp,strcpy,strerror,strspn,strchr等) 作者:一只青木呀 ...

  8. 字符函数和字符串函数详解(二)strncpy strncat strncmp strstr strtok(及其模拟实现)

     系列文章目录 字符函数和字符串函数详解(一)strlen strcpy strcat strcmp 字符函数和字符串函数详解(二)strncpy strncat strncmp strstr str ...

  9. C语言字符串函数的详解

    一.字符串具体有哪些 求字符串的长度 strlen 长度不受限制的字符串函数 strcpy strcat strcmp 长度受限制的字符串函数介绍 strncpy strncat strncmp 字符 ...

最新文章

  1. Java Web整合开发读书笔记
  2. 重磅!2021泰晤士世界大学排名公布,清华排名首次挺进top20
  3. 列表,集合,元组,字典
  4. mysql主从同步默认延迟_减少mysql主从数据同步延迟问题的详解
  5. android后台获取view,android – 如何获取当前显示在AdapterView中的项目?
  6. [C语言]为什么要有include?——从Hello World说起
  7. BCVP开发者说第4期:Remember.Core
  8. 去马赛克神器 JavPlayer TG Modle 最新版
  9. 地方时太阳时html源码,地方时和标准时(25页)-原创力文档
  10. mathematic语法基础
  11. php语言grads画图,grads画图坐标设置.docx
  12. html5 队列展示,设计一个队列研究实例
  13. matlab 光栅 傅里叶,【图像】【转帖】利用matlab绘制光栅条纹图像
  14. 企业大楼AI无感考勤解决方案
  15. 头条自媒体运营秘籍,坚持下去你就可以打败90%的人
  16. 每日词根——sol(完整可靠安慰,太阳严肃)
  17. 腾讯云服务器使用中遇到的问题
  18. Eastmoney-Spyder:股吧网页数据抓取分析(一)
  19. 比较好的android 手机号码,安卓手机最好的系统(五大公认最好用的安卓手机系统)...
  20. 2022制冷与空调设备运行操作国家题库模拟考试平台操作

热门文章

  1. 你在乎的--世界在乎的
  2. 第六章 Qt布局管理器Layout
  3. Dede cms文章内容管理系统安全漏洞!如何有效防止DEDE织梦系统被挂木马安全设置...
  4. 使用SharePoint 2010新增的文档集内容类型来管理文档
  5. Eclipse to android
  6. [LaunchPad] 超声波测试,数码管显示
  7. 校验输入框的内容不能重复_答应我,用了这个jupyter插件,别再重复造轮子了
  8. linux下删除乱码文件名的方法
  9. 干货:产品经理怎么做才能在需求评审中少挨打?
  10. 如何做好内容策划并完成一篇合格的深度文?