zoukankan      html  css  js  c++  java
  • 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("
    ");
      my_memset(a,0,sizeof(a));
      for(int i = 0; i < sizeof(a) / sizeof(int); ++i){
        printf("%d ", *(a+i));
      }
      printf("
    ");
    }
    
    

    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
    ");
      else if(res > 0)
        printf("s1 > s2
    ");
      else
        printf("s1 < s2
    ");
    
      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
    ");
      else if(res1 > 0)
        printf("i1 > i2
    ");
      else
        printf("i1 < i2
    ");
    
    }
    
    

    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]
    ", s1);
      printf("s3 = [%s]
    ", s3);
    
    
      char s11[20] = {'a','b','c','d'};
      char *s22 = "xyzdef";
    
      char *s33 = memcpy(s11+1,s11,3);
      printf("s11 = [%s]
    ", s11);
      printf("s33 = [%s]
    ", 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("
    ");
    
      for(int i = 0; i < sizeof(i2) / sizeof(int); ++i){
        printf("i3[%d] = %d ",i, pi3[i]);
      }
      printf("
    ");
    
    }
    

    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]
    ", s1);
      printf("s3 = [%s]
    ", s3);
    
    
      char s11[20] = {'a','b','c','d'};
      char *s22 = "xyzdef";
    
      char *s33 = memmove(s11,s11+1,3);
      printf("s11 = [%s]
    ", s11);
      printf("s33 = [%s]
    ", 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("
    ");
    
      for(int i = 0; i < sizeof(i2) / sizeof(int); ++i){
        printf("i3[%d] = %d ",i, pi3[i]);
      }
      printf("
    ");
    }
    
  • 相关阅读:
    状压DP
    题解:中位数
    题解:三只小猪
    二分图最大匹配
    AC自动机
    题解 P1137 【旅行计划】
    题解 P1280 【尼克的任务】
    DFT&IDFT学习笔记
    emacs配置
    莫比乌斯反演推导即μ函数的证明
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/9185344.html
Copyright © 2011-2022 走看看