memset memcmp memcpy memmove 自己实现

memset

#include <stdio.h>
#include <memory.h>
#include <assert.h> void* my_memset(void* dest, int c, size_t cnt){
assert(NULL != dest);
char *a = (char*)dest;
while(cnt-- > 0){
*a++ = c;
} return dest;
}
int main(){
int a[10];
for(int i = 0; i < sizeof(a) / sizeof(int); ++i){
printf("%d ", *(a+i));
}
printf("\n");
my_memset(a,0,sizeof(a));
for(int i = 0; i < sizeof(a) / sizeof(int); ++i){
printf("%d ", *(a+i));
}
printf("\n");
}

memcmp

#include <stdio.h>
#include <memory.h>
#include <assert.h> int my_memcmp(const void* s1, const void* s2, size_t cnt){
assert(NULL != s1 && NULL != s2); const char *t1 = s1;
const char *t2 = s2; int res = 0;
while(cnt-- > 0){
if(*t1 > *t2){
res =1;
break;
}
else if(*t1 < *t2){
res = -1;
break;
}
else{
t1++;
t2++;
}
} return res;
} int main(){
char* s1 = "abcdaaa";
char *s2 = "abcdaa"; int res = my_memcmp(s1,s2,18);
if(0 == res)
printf("s1 == s2\n");
else if(res > 0)
printf("s1 > s2\n");
else
printf("s1 < s2\n"); int i1[] = {255,2,3,4,5};
int i2[] = {511,22,23,5}; int res1 = my_memcmp(i1,i2,1);
if(0 == res1)
printf("i1 == i2\n");
else if(res1 > 0)
printf("i1 > i2\n");
else
printf("i1 < i2\n"); }

memcpy

如果copy元的首地址 + copy的字节数的结果 >= copy先的首地址的话,就会出现覆盖,得不到正确的结果。

下面的实现结果太笨了,倒过来复制是最简单的,请看后面的memmove的实现方式。

include <stdio.h>
#include <memory.h>
#include <assert.h>
#include <malloc.h> void* my_memcpy(void* dest, const void* src, size_t cnt){ assert(NULL != dest && NULL != src); char *tmp = dest;
const char *st = src; //判断元的首地址+要copy的字节数是否大于copy先的首地址
size_t bit = st + cnt - tmp;
char *tt = NULL;
char *tm = NULL; //为了free使用
char *ta;
//如果copy的首地址大于元的首地址,并且元的首地址+要copy的字节数是否大于copy先的首地址,覆盖就会发生,所以要把将被覆盖的一段内存保存下来,先开辟空间(空间大小是bit),对tt的赋值,在后面的while里。
if(tmp > st && bit > 0){
tt = (char*)malloc(bit);
}
//由于tt被用于赋值(初始化),所以tt已经不是首地址了;当copy到被覆盖的字节的时候,要从首地址拿值,所以从tm中拿值,不从st中拿值;ta一直指向开辟空间的首地址,最后用于释放这个开辟的空间。
ta = tm = tt; while(cnt-- > 0){
//tt不为NULL,就是说明了,将要发生覆盖,所以把要被覆盖的字节存放到tt中,但要注意不发生覆盖的字节不需要存放进去,所以加了bit-- > 0的条件
if(NULL != tt && bit-- > 0){
*tt++ = *tmp;
}
//NULL != tt说明了,是覆盖patten,并且到了要被覆盖的字节,所以不从st中取值,从tm中取值。
if(st >= (char*)dest && NULL != tt){
*tmp++ = *tm++;
st++;
}
//说明不是覆盖的patten,无脑复制就可以了。
else{
*tmp++ = *st++;
} }
free(ta);
return dest;
} int main(){
char s1[20] = {'a','b','c','d'};
char *s2 = "xyzdef"; //char *s3 = memcpy(s1+1,s1,3);
char *s3 = my_memcpy(s1+1,s1,3);
printf("s1 = [%s]\n", s1);
printf("s3 = [%s]\n", s3); char s11[20] = {'a','b','c','d'};
char *s22 = "xyzdef"; char *s33 = memcpy(s11+1,s11,3);
printf("s11 = [%s]\n", s11);
printf("s33 = [%s]\n", s33); int i1[10] = {1,2};
int i2[10] = {11,22,33,3};
int i3[10] = {1};
int *pi3 = i3;
pi3 = (int*)my_memcpy(i2+2,i2,sizeof(int) * 3);
for(int i = 0; i < sizeof(i2) / sizeof(int); ++i){
printf("i1[%d] = %d ",i, i2[i]);
}
printf("\n"); for(int i = 0; i < sizeof(i2) / sizeof(int); ++i){
printf("i3[%d] = %d ",i, pi3[i]);
}
printf("\n"); }

memmove

#include <stdio.h>
#include <memory.h>
#include <assert.h> void* my_memmove(void* dest, const void* src, size_t cnt){ assert(NULL != dest && NULL != src); char* tmp = dest;
const char* st = src;
//判断出是覆盖的patten,所以从后往前覆盖
if(tmp > st && st + cnt > tmp){
while(cnt-- > 0){
*(tmp + cnt) = *(st + cnt);
}
}
//判断出不是覆盖的patten,所以无脑从前往后覆盖
else {
while(cnt-- > 0){
*tmp++ = *st++;
}
} return dest;
} int main(){
char s1[20] = {'a','b','c','d'};
char *s2 = "xyzdef"; char *s3 = my_memmove(s1,s1+1,3);
printf("s1 = [%s]\n", s1);
printf("s3 = [%s]\n", s3); char s11[20] = {'a','b','c','d'};
char *s22 = "xyzdef"; char *s33 = memmove(s11,s11+1,3);
printf("s11 = [%s]\n", s11);
printf("s33 = [%s]\n", s33); int i1[10] = {1,2};
int i2[10] = {11,22,33,3};
int i3[10] = {1};
int *pi3 = i3;
pi3 = (int*)my_memmove(i2+2,i2,sizeof(int) * 3);
for(int i = 0; i < sizeof(i2) / sizeof(int); ++i){
printf("i1[%d] = %d ",i, i2[i]);
}
printf("\n"); for(int i = 0; i < sizeof(i2) / sizeof(int); ++i){
printf("i3[%d] = %d ",i, pi3[i]);
}
printf("\n");
}

memset memcmp memcpy memmove 自己实现的更多相关文章

  1. 自己实现的库函数2(memset,memcmp,memcpy,memmove)

    memset,memcmp,memcpy,memmove是对内存进行管理的库函数,为了更好的理解和使用这几个函数,自己用C语言实现一下~ //内存设置函数void* my_memset(void* d ...

  2. 自己实现内存操作函数memset(),memcmp(),memcpy(),memmove()

    1.memset()内存设置函数(初始化) void *my_memset(void* dest, int c, size_t count) { assert(dest != NULL); char  ...

  3. 走进C标准库(7)——"string.h"中函数的实现memcmp,memcpy,memmove,memset

    我的memcmp: int memcmp(void *buf1, void *buf2, unsigned int count){ int reval; while(count && ...

  4. memcpy/memmove?快速乘?

    memcpy?memmove? //#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; ; ],b[n ...

  5. <cstring>中常用的两个函数memset()和memcpy()

    <cstring>是c++对c中的<string.h>进行了重写,这两个头文件中的函数用法是一样的,所以在用的时候包含哪个头文件都行.下面介绍一下 <cstring> ...

  6. C的memset,memcpy,strcpy 的区别 及memset memcpy memmove源码

    extern void *memcpy(void *dest,void *src,unsigned int count);#include <string.h>   功能:由src所指内存 ...

  7. memset,memcpy,memmove,strcpy,strcat,strcmp的实现(其实很简单,每个程序都只有几行代码)

    面试中的几个小问题 1.对stl中list封装(参考1): 2.对重要C函数实现(参考2): //memset void *memset(void *buffer, int c, int count) ...

  8. c语言中几个常见的库函数strlen、strcmp、strcat、strcpy、strncpy、memset、memcpy、memmove、mmap

    1.strlen() 1)计算给定字符串的长度,不包括’\0’在内 unsigned int strlen(const char *s) { assert(NULL != s);//如果条件不满足,则 ...

  9. memcpy memmove区别和实现

    memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中. 但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开 ...

随机推荐

  1. python 时间模块time,datetime

    模块(module)是 Python 中非常重要的东西,你可以把它理解为 Python 的扩展工具.换言之,Python 默认情况下提供了一些可用的东西,但是这些默认情况下提供的还远远不能满足编程实践 ...

  2. 手把手使用Docker搭建SpringBoot微服务镜像

    一.环境准备 1.安装好Docker环境的Linux机器(安装教程) 2.准备好SpringBoot项目打包好的可运行jar包 二.编写Dockerfile 1.首先将SpringBoot打包好的ja ...

  3. linux常用命令学习笔记

    1.top命令 作用:该命令可以按CPU使用.内存使用和执行时间对任务进行排序,常用来监控系统中占用CPU或内存较高的程序及CPU和内存的负载. 默认视图: 当想看系统负载时,可观察汇总的%CPU中的 ...

  4. Python 的名称空间和作用域

    最开始对名称空间的了解是在学习函数的时候,那时候知道了作用域的查找顺序,以及全局名称空间和局部名称空间,产生疑惑的时候为学递归的时候,那时候还没有名称空间这个概念,只知道递归有个最大深度,那时候以后递 ...

  5. IIS应用程序池_缓存回收

    本人最近由于公司业务,需要把问卷的问题和答案存入缓存中已提高问卷加载速度,减少数据库压力. 缓存关键代码(公司代码已做封装,这里只贴出关键代码): HttpRuntime.Cache.Insert(k ...

  6. mysql中union 查询

    UNION ALL只是简单的将两个结果合并后就返回.这样,如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了. 从效率上说,UNION ALL 要比UNION快很多,所以,如果可 ...

  7. 学习HttpClient,从两个小例子开始

    前言 HTTP(Hyper-Text Transfer Protocol,超文本传输协议)在如今的互联网也许是最重要的协议,我们每天做的很多事情都与之有关,比如,网上购物.刷博客.看新闻等.偶尔你的上 ...

  8. Hibernate入门(三)

    持久化类的编写规则: 1.持久化类需要提供无参的构造方法.因为在Hibernate的底层需要使用反射生成的实例. 2.持久化类的属性需要私有,对私有的属性提供共有的get和set方法.因为在Hiber ...

  9. HTML设为首页/加入收藏代码

    (特别注意:要把'这个符号换成无任何输入法状态中输入的'这个符号,否则程序无法运行)   1.文字型:     <a onclick="this.style.behavior='url ...

  10. hihoCoder编程练习赛52

    题目1 : 字符串排序 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 一般我们在对字符串排序时,都会按照字典序排序.当字符串只包含小写字母时,相当于按字母表" ...