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所指内存区域. 说明 ...
随机推荐
- 页面中多个script块之间方法与变量共享问题
JS是按照代码块来进行编译和执行的,代码块间相互独立,但变量和方法共享,按顺序执行. 如: <script type='text/javascript'> var m = 0,n = 1, ...
- drupal7 获取profile2模块自定义字段的值
$user=user_load($uid); $student=profile2_load_by_user($user,'student'); 这个函数官方有文档,通过用户对象返回用户的profile ...
- JS--我发现,原来你是这样的JS(一)(初识,历史)
一.前言: 前段时间看红宝书(JavaScript高级程序设计),但没有计划的去看,也没有做详细的笔记,读了之后有点空虚,感觉不对劲啊,学的东西很难记住,印象不深啊,有种挫败感. 作前端的js都学不好 ...
- plsql 导出查询结果
点击青色按钮即可 说明: 会将查询到的所有数据导出到指定文件,并不是只导出下面列表显示的几行数据: 也不用点击"获取最后页"那个按钮. 注意: 当你选择导出为excel文件时, ...
- 关于Mobx中装饰器语法的环境配置
1.弹出项目配置 npm run eject 此处注意,若弹出项目配置失败,请先执行以下两行代码(若没有安装git则请跳过,本人是在安装git的情况下解决问题的) 1.git add . 2.git ...
- [Android] 对自定义图片浏览器经常内存溢出的一些优化
首先关于异步加载图片可以参见 夏安明 的博客:http://blog.csdn.net/xiaanming/article/details/9825113 这篇文章最近有了新的更改,大概看了一下,内容 ...
- 8.1、包,__init__.py,
包: 为了组织好模块,将多个模块组合为一个包,所以包用于存放python模块 包通常是一个文件夹,当文件夹当作包使用时,文件夹需要包含__init__.py文件 __init__.py的内容可以为空, ...
- CSS样式----css样式表和选择器(图文详解)
本文最初于2015-10-03发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 本文主要内容 CSS概述 CSS和HTML结合的三种方式:行内样 ...
- 对C#Chart控件使用整理
转:https://blog.csdn.net/andrewniu/article/details/78770186 https://blog.csdn.net/andrewniu/article/d ...
- Oracle EBS AP 取消发票
--取消发票 created by jenrry 20170425 declare l_result BOOLEAN; l_message_name VARCHAR2(240); l_invoice_ ...