memcpy、memmove、memset、memchr、memcmp、strstr详解
第一部分 综述
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所指的内存区域不可重叠
重叠实例:
- #include<iostream>
- #include<string.h>
- using namespace std;
- int main()
- {
- int a[] = {};
- for (int i = ; i < ; i++)
- a[i] = i;
- memcpy(&a[],a,sizeof(int)*);
- //memmove(&a[4], a, sizeof(int) * 6);
- for (int i = ; i < ; i++)
- cout << a[i];
- getchar();
- return ;
- }
会输出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的指针
上面的例子可以改一下
- int a[] = {};
- memset(a,,);
4、memchr()--查找内存内容
表头文件:#include<string.h>
函数说明:从buf所指内存区的前count个字节查找字符ch,当第一次遇到字符ch时停止查找。如果成功,返回指向字符ch的指针;否则返回null
定义函数:extern void* memchr(const void* buf,int ch,size_t count)
代码实现
- #include<iostream>
- #include<string.h>
- using namespace std;
- int main()
- {
- char a[] = "nihao jingliming";
- void *p;
- p = memchr(a,'j',sizeof(a));
- if (p)
- cout << "has found:" << *((char*)p) << endl;
- else
- cout << "not found" << endl;
- getchar();
- return ;
- }
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
函数说明:该函数是按字节进行比较的
- #include<iostream>
- #include<string.h>
- using namespace std;
- int main()
- {
- char a[] = "nihao jingliming";
- char b[] = "nihao xiaoming";
- int r=memcmp(a,b,strlen(a));
- if (r>)
- cout << "a is big" << endl;
- else if (r < )
- cout << "b is big" << endl;
- else
- cout << "same" << endl;
- getchar();
- return ;
- }
第三部分 实现
memcpy和memmove
linux内核版
- /**
- * memcpy - Copy one area of memory to another
- * @dest: Where to copy to
- * @src: Where to copy from
- * @count: The size of the area.
- *
- * You should not use this function to access IO space, use memcpy_toio()
- * or memcpy_fromio() instead.
- */
- void * memcpy(void * dest,const void *src,size_t count)
- {
- char *tmp = (char *) dest, *s = (char *) src;
- while (count--)
- *tmp++ = *s++;
- return dest;
- }
- /* Normally compiler builtins are used, but sometimes the compiler calls out
- of line code. Based on asm-i386/string.h.
- */
- #define _STRING_C
- #include <linux/string.h>
- #undef memmove
- void *memmove(void * dest,const void *src,size_t count)
- {
- if (dest < src) {
- __inline_memcpy(dest,src,count);
- } else {
- char *p = (char *) dest + count;
- char *s = (char *) src + count;
- while (count--)
- *--p = *--s;
- }
- return dest;
- }
window版
- void * __cdecl memcpy (void * dst, const void * src, size_t count)
- {
- void * ret = dst;
- /*
- * copy from lower addresses to higher addresses
- */
- while (count--) {
- *(char *)dst = *(char *)src;
- dst = (char *)dst + ;
- src = (char *)src + ;
- }
- return(ret);
- }
- void * __cdecl memmove (void * dst, const void * src, size_t count)
- {
- void * ret = dst;
- if (dst <= src || (char *)dst >= ((char *)src + count)) {
- /*
- * Non-Overlapping Buffers
- * copy from lower addresses to higher addresses
- */
- while (count--) {
- *(char *)dst = *(char *)src;
- dst = (char *)dst + ;
- src = (char *)src + ;
- }
- }
- else {
- /*
- * Overlapping Buffers
- * copy from higher addresses to lower addresses
- */
- dst = (char *)dst + count - ;
- src = (char *)src + count - ;
- while (count--) {
- *(char *)dst = *(char *)src;
- dst = (char *)dst - ;
- src = (char *)src - ;
- }
- }
- return(ret);
- }
windows写的就是分析的更详细,效率更快。
memset
- void *(memset) (void *s,int c,size_t n)
- {
- const unsigned char uc = c;
- unsigned char *su;
- for(su = s; < n;++su,--n)
- *su = uc;
- return s;
- }
memchr
- void *memchr (const void *ptr, int value, int num)
- {
- if (ptr == NULL)
- {
- perror("ptr");
- return NULL;
- }
- char * p = (char *)ptr;
- while (num--)
- {
- if (*p != (char)value)
- p++;
- else
- return p;
- }
- return NULL;
- }
memcmp
- /* 因为类型可以为任意,所以形参应为void *
- * 相等则返回0,否则不为0
- */
- int my_memcmp(const void *s1,const void *s2,size_t count)
- {
- int res = ;
- const unsigned char *p1 =(const unsigned char *)s1;//注意是unsigned char *
- const unsigned char *p2 =(const unsigned char *)s2;
- for(p1 ,p2;count > ;p1++,p2++,count--)
- if((res =*p1 - *p2) != ) //不相当则结束比较
- break;
- return res;
- }
ststr实现
- char* strstr(const char *s1, const char *s2)
- {
- int n;
- if (*s2)
- {
- while (*s1)
- {
- for (n=; *(s1 + n) == *(s2 + n); n++)
- {
- if (!*(s2 + n + ))
- return (char *)s1;
- }
- s1++;
- }
- return NULL;
- }
- else
- return (char *)s1;
- }
memcpy、memmove、memset、memchr、memcmp、strstr详解的更多相关文章
- 走进C标准库(7)——"string.h"中函数的实现memcmp,memcpy,memmove,memset
我的memcmp: int memcmp(void *buf1, void *buf2, unsigned int count){ int reval; while(count && ...
- [转]keil使用详解
第一节 系统概述 Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上.结构性.可读性.可维护性上有明显的优势,因而易学易用.用过 ...
- KeilC51使用详解 (三)
C51强大功能及其高效率的重要体现之一在于其丰富的可直接调用的库函数,多使用库函数使程序代码简单,结构清晰,易于调试和维护,下面介绍C51的库函数系统. 第一节 本征库函数(intrinsic rou ...
- C-基础:memcpy、memset、memmove、memcmp、memchr
一,原型 void * memcpy ( void * destination, const void * source, size_t num ); 功能:将以source作为起始地址的数据复制nu ...
- 自己实现的库函数2(memset,memcmp,memcpy,memmove)
memset,memcmp,memcpy,memmove是对内存进行管理的库函数,为了更好的理解和使用这几个函数,自己用C语言实现一下~ //内存设置函数void* my_memset(void* d ...
- memset memcmp memcpy memmove 自己实现
memset memcmp memcpy memmove 自己实现 memset #include <stdio.h> #include <memory.h> #include ...
- memset函数详解
语言中memset函数详解(2011-11-16 21:11:02)转载▼标签: 杂谈 分类: 工具相关 功 能: 将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值, 块的大 ...
- memset用法详解
原文:http://www.cnblogs.com/PegasusWang/archive/2013/01/20/2868824.html 1.void *memset(void *s,int c,s ...
- c++中内存拷贝函数(C++ memcpy)详解
原型:void*memcpy(void*dest, const void*src,unsigned int count); 功能:由src所指内存区域复制count个字节到dest所指内存区域. 说明 ...
随机推荐
- 关于ajax 传递的参数
ajax 发送的数据,默认都是字符串,不能直接传递list(列表),或者dict(字典). 若要 传递list(列表),或者dict(字典),需要进行一些操作. list 需要进行列表序列化,在aja ...
- my big day is coming!
明天博士学位论文答辩,给自己加油! 期望一切顺利!
- JUnit手动设计测试方法以及与Randoop的自动生成测试的比较
手动设计测试 在已有的web project本地目录lib文件夹里导入两个jar文件(版本可不一样):junit-4.12.jar和hamcrest.jar 打开eclipse,导入项目,右击项目选择 ...
- python 使用else代替状态变量
翻看公司的代码文档,在代码风格文档中,写着:为了提高代码的可维护性,代码中减少flag这类状态变量的使用.这个问题,平时确实没有想过,面对这种需求时,第一反应就是使用flag标记状态.那么使用什么样的 ...
- python + Jenkins + requests 数据驱动接口测试 环境部署
** Jenkins安装: * 安装包选择:Jenkins.war * windows下有msi和war两种格式,我使用的是war,下载下来丢到xmapp的指定目录就行,操作方便一点 * m ...
- Python Socket 通信
参考: http://www.cnblogs.com/alex3714/articles/5830365.html Socket A network socket is an endpoint of ...
- zabbix agent 3.4 安装指南
从官方网站www.zabbix.com 下载zabbix agent安装包.目前最新版本是4.0 LTS release. 在需要监控的服务器上安装zabbix agent. 先解压安装包. 配置 c ...
- Sql server的Merge语句,源表中如果有重复数据会导致执行报错
用过sql server的Merge语句的开发人员都应该很清楚Merge用来做表数据的插入/更新是非常方便的,但是其中有一个问题值得关注,那就是Merge语句中的源表中不能出现重复的数据,我们举例来说 ...
- pt-osc原理、限制、及与原生online-ddl比较
1. pt-osc工作过程 创建一个和要执行 alter 操作的表一样的新的空表结构(是alter之前的结构) 在新表执行alter table 语句(速度应该很快) 在原表中创建触发器3个触发器分别 ...
- python下以api形式调用tesseract识别图片验证码
一.背景 之前在博文中介绍在python中如何调用tesseract ocr引擎,当时主要介绍了shell模式,shell模式需要安装tesseract程序,并且效率相对略低. 今天介绍api形式的调 ...