这三个函数都是内存拷贝,目的都是将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个字节,不会因为遇到字符串结束'\0'而结束



                  strcpy和memcpy主要有以下3方面的区别。


            1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、                              结构体、类等。



            2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢                               出。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函数功能相同。












      函数实现:

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中数据输出已被更改。 



  原因|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','\0'}; 
  char p[2]={'q','w'};//或char *p=a+2;
  memmove(p,a,sizeof(a));
     puts(a);
  printf("_____________________________________________\n");
  puts(p);
  printf("_____________________________________________\n");
   for(i =0;i<10;i++)
    printf("%c %d \n",*(a+i),a+i);
  printf("_____________________________________________\n");
  for(i =0;i<8;i++)
   printf("%c %d \n",*(p+i),p+i); 
    return 0;
      }


观察输出结果。  
      把memmove(p,a,sizeof(a));改为memcpy(p,a,sizeof(a));或memccpy(p,a,'e',sizeof(a));再观察输出结果。  
      可以看出在目的存储空间不足时,便会出现源数据被覆盖改变的问题。  如果目的存储空间分配足够的空间,则便不会出现覆盖问题。