memset memcmp memcpy memmove 自己实现

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");
}

原文地址:https://www.cnblogs.com/xiaoshiwang/p/9185344.html

时间: 2024-11-05 20:39:26

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

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

我的memcmp: 1 int memcmp(void *buf1, void *buf2, unsigned int count){ 2 int reval; 3 while(count && !(reval = (*(unsigned char *)buf1) - (*(unsigned char *)buf2))) 4 { 5 buf1 = (unsigned char *)buf1 + 1; 6 buf2 = (unsigned char *)buf2 + 1; 7 --count

模拟实现部分库函数(strcpy,strcmp,strcat,strstr,memcpy,memmove,memset)

//1.strcpy(拷贝) char* my_strcpy(char*dst, const char*src) {  assert(dst);  assert(src);  char* cp = dst;  while (*cp++ = *src++)  {   ;  }  return dst; } //2.strcat(连接) char* my_strcat(char*dst, const char*src) {  assert(dst);  assert(src);  char* cp 

memset,memcpy

memset:是计算机中C/C++语言函数. 解释:将s所指向的某一块内存中的前n个 字节的内容全部设置为ch指定的ASCII值, 第一个值为指定的内存地址,块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 其返回值为指向s的指针. 函数:void *memset(void *s, int ch, size_t n); 函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s .memset:作用是在一段内存块

memset 与 memcpy

1. memset 需要的头文件 在C中 <string.h> 在C++中 <cstring> 原型: void *memset(void *s, int ch, size_t n); 用法: memset是计算机中C/C++语言函数.将s所指向的某一块内存中的前n个字节的内容全部设置为ch指定的ascii值, 第一个值为指定的内存地址,块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 其返回值为指向s的指针. 函数解释:将s中当前位置后面的n个字节 (typed

C语言模拟实现memcpy,memmove函数

这里memcpy与memmove函数的模拟实现,需要用到空指针来传递参数,之后强制类型转换为char型,用size_t这个宏接受偏移量进行偏移,模拟实现如下: memcpy函数: void* my_memcpy(void*dst,const void*src ,size_t count) { assert(dst); assert(src); void* ret = dst; while (count--) { *(char*)dst = *(char*)src; dst = (char*)ds

C语言 strcpy,memcpy,memmove,memccpy函数

1.原型:extern char *strcpy(char *dest,char *src); 用法:#include <string.h> 功能:把src所指由NULL结束的字符串复制到dest所指的数组中. 说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串. 返回指向dest的指针. 2.原型:extern void *memcpy(void *dest, void *src, unsigned int count); 用法:#include &l

memset和memcpy函数、atoi函数

1.void *memset(void *s,int c,size_t n) 总的作用:将已开辟内存空间 s 的首 n 个字节的值设为值 c. 2.例子 #include void main(){ char *s="Golden Global View"; clrscr(); memset(s,'G',6); printf("%s",s); getchar(); return 0; } 3.memset() 函数常用于内存空间初始化.如: char str[100]

C++ 对象模型详细讲解(特别容易理解)

c++对象模型系列 转 一.指针与引用 一 概括 指针和引用,在C++的软件开发中非常常见,如果能恰当的使用它们能够极大的提 高整个软件的效率,但是很多的C++学习者对它们的各种使用情况并不是都了解,这就导致了实际的软件开发中经常会内存泄漏,异常抛出,程序崩溃等问题.对 于C和C++的初学者,那更是被它们搞的迷迷糊糊.本篇作为[深入C++]系列的第一节,我们就带领大家把指针和引用这个基本功练好. 二 指针 指针,指针的定义是什么呢?好像要想给个直接的定义还是很难的哦,所以我们这里用它的语法结合图

linux常用C函数目录

字符测试篇 isalnum isalpha isascii iscntrl isdigit isgraphis islower isprint isspace ispunct isupper isxdigit 字符串转换篇 atof atoi atol gcvt strtod strtol strtoul toascii tolower toupper 内存控制篇 calloc free getpagesize malloc mmap munmap 日期时间篇 asctime ctime get