• memmove、memccpy和memcpy


    这三个函数都是内存拷贝,目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中。 

          void *memmove(void *dest,void*src,int count)
         void *memcpy(void *dest,void *src,int count)
          void *memccpy(void*dest,void*src,int ch,int count)
     
           头文件 :#include <string.h>
           函数原型 : void *memcpy(void *dest, const void *src, size_t n)
           函数说明 : memcpy()用来拷贝src所指的内存内容前n个字节到dest所指的内存地址上。与strcpy()不同的                         是,memcpy()会完整的复制n个字节,不会因为遇到字符串结束''而结束
                      strcpy和memcpy主要有以下3方面的区别。
                1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、                              结构体、类等。
                2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符""才结束,所以容易溢                               出。memcpy则是根据其第3个参数  决定复制的长度。
                3 、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy
            返回值:   返回指向dest的指针
           函数实现:
    void* memcpy(void* dest,const void* src, size_t n)
     {
        assert(dest!=NULL && src != NULL);
        char* d=dest;
      const char* s=src;
                    while(n--)
                       *d++ = *s++;
             return dest;
             }
     
     
          头文件: #include <string.h>
         函数原型: void *memccpy(void *dest, const void *src, int c, size_t n);
         函数说明:memccpy()用来拷贝src所指的内存内容前n个字节到dest所指的地址上。与memcpy()不同的                           是,memccpy()如果在src中遇到某个特定值(int c)立即停止复制。
         返回值:  如果c没有被复制,则返回NULL,否则,返回dest中字符c 后面紧挨一个字符位置的指针
         函数实现:
    void* memccpy(void* dest,const void* src, int c, size_t n)
            {
         assert(dest!=NULL && src != NULL);
         while( n )
    {
    *(char *) dest = *(char *)srcl;
    dest = (char *)dest + 1;
    if(*(char *)src == (char)c)
    break;
    src = (char *)src + 1;
    n--;
    }
             return (n ? dest : NULL);
            }
     
           头文件: #include <string.h>
           函数原型: void *memmove(void *dest, const void *src, size_t n);
           函数说明:由src所指内存区域复制count个字节到dest所指内存区域。如果目标区域和源区域有重叠的话,                      memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开销。memmove能够保证源                串在被覆盖之前将重叠区域的字节拷贝到目标区域中。但复制后src内容会被更改。但是当目标区域与源区域                没有重叠则和memcpy函数功能相同。
                 memmove的处理措施:
                        (1)当源内存的首地址等于目标内存的首地址时,不进行任何拷贝
                       (2)当源内存的首地址大于目标内存的首地址时,实行正向拷贝
                       (3)当源内存的首地址小于目标内存的首地址时,实行反向拷贝
          函数实现:
                 void *memmove(void *dest, const void *src, size_t n)
                {
    assert(dest!=NULL && src != NULL);
    char *d = (char *)dest;
    const char* s = (const char*)src;
    if(s > d)
    {
    while(n--)
    *d++ = *s++;
    }
    else if(s < d)
    {
    d = d + n - 1;
    s = s + n - 1;
    while(n--)
    *d-- = *s--;
    }
    return dest;
       }
     
     
     
    当dest <= src-count 或dest >= src+count时,以上三个函数均不会产生覆盖问题,即源数据不会被更改。
      若不在以上范围内,则源数据会被更改。  如: 
    char a[]={'a','b'}; 
    char b[]={'c','d','e','f','g','h'};  
       memmove(a,b,sizeof(b)); 
    或是直接char *p=b+2;memmove(p,b,sizeof(b));  
      输出数据会发现b中数据输出已被更改。 
           发现即使a数组指向的空间不够存储数据,也能够移动成功。 
      原因|dest - src |<count 
    如果在使用这些函数时,分配给足够的空间,然后再使用就不会出现覆盖问题。也就是
    说如果外部分配给的空间不足以存储要拷贝的数据时,就有可能出现源数据被覆盖更改
    的问题。
     
    #include<stdio.h>
         #include<stdlib.h>
         #include<string.h>

         int main()
        {
             int i=0; 
      char a[9]={'a','b','c','d','e','f','g','h',''}; 
      char p[2]={'q','w'};//或char *p=a+2;
      memmove(p,a,sizeof(a));
        puts(a);
      printf("_____________________________________________ ");
      puts(p);
      printf("_____________________________________________ ");
      for(i =0;i<10;i++)
        printf("%c %d ",*(a+i),a+i);
      printf("_____________________________________________ ");
      for(i =0;i<8;i++)
      printf("%c %d ",*(p+i),p+i); 
        return 0;
         }
     
    观察输出结果。  
          把memmove(p,a,sizeof(a));改为memcpy(p,a,sizeof(a));或memccpy(p,a,'e',sizeof(a));再观察输出结果。  
          可以看出在目的存储空间不足时,便会出现源数据被覆盖改变的问题。  如果目的存储空间分配足够的空间,则便不会出现覆盖问题。 
     
    http://blog.csdn.net/q5707802/article/details/27236619
  • 相关阅读:
    HDU1542矩形面积并
    HDU5869树状数组+gcd预处理
    HDU5845 Best Division
    整体二分
    Lattice 的 Framebuffer IP核使用调试笔记之datasheet笔记
    DDR3详解(以Micron MT41J128M8 1Gb DDR3 SDRAM为例)
    ISD1700系列多段语音录放系列
    Lattice Diamond 学习之编译、检查和设置约束
    欧拉函数的几个性质及证明
    CF776B Sherlock and his girlfriend
  • 原文地址:https://www.cnblogs.com/findumars/p/4896396.html
Copyright © 2020-2023  润新知