概述:
  1:strncpy和strncpy主要是用于字符串的拷贝。
  2:而memcpy()和memmove()则适用于所有的数据类型。
  3: memcpy()和memmove()这两者的区别在于内存重叠的处理。
  4:本文给出的代码都是基于函数的功能所写的代码,不一定是官方的实现代码。但是实现的功能是一样的。
  展开:
  /*************************************************/
  1.strcpy()函数
  /*************************************************/
  1 原型:
  char *strcpy(char* dest, const char *src);
  2 定义
  把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间
  3 拷贝终止条件
  当src字符结束时,把src末尾的’’也拷贝过来,复制结束。
  4 代码实现
  自己取函数名为mystrcpy();
  char * mystrcpy(char *dst,const char* src)
  //源字符串不能改变,所以const修饰
  {
  assert(dst!=NULL&&src!=NULL);//断言方式确保指针不为空
  char* p=dst;
  while((*p++=*src++)!='');//逐个复制 直到*src='',注意src末尾的''也要拷贝过来
  return dst;//返回的是目标字符串的首地址dst,在这里不能返回指针p
  }
  /*************************************************/
  2.strncpy()函数
  /*************************************************/
  1 原型
  strncpy()的原型是
  char* strncpy(char*dest, char*src, size_t n);
  其中:n为指定的拷贝的字节长度。
  2 定义
  :(c/c++)复制字符串src中的内容(字符,数字、汉字….)到字符串dest中,复制多少由size_tn的值决定。如果src的前n个字符不含NULL字符,则结果不会以NULL字符结束。
  如果n<src的长度,只是将src的前n个字符复制到dest的前n个字符,不自动添加’’,也是结果dest不包括’’,需要再手动添加一个’’。如果src的长度小于n个字节,则以NULL填充dest直到复制完n个字节。src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符长度+’’。
  3 拷贝终止条件:
  3-1:n<=strlen(src)+1,复制n个字符,不自动加''
  3-2: n>strlen(src)+1,复制完src之后,因为复制次数还没有达到n,所以后面的每一次都是往dst补零,直到复制次数到达n.
  代码实现
  char* mystrncpy(char* dst, const char*src ,unsigned int n)
  {
  assert(dst!=NULL&&src!=NULL);//断言
  char *pdst=dst;
  while(n&&(*pdst++=*src++)!=''){n--;}//注意此处n--不要放在while()的比较表达式里面。
  if(n)
  {
  while(n--)
  {
  *pdst++='';
  }
  }
  return dst;
  }
  /*************************************************/
  3.memcpy()函数
  /*************************************************/
  1原型:
  memcpy()的原型是
  void *memcpy(void *dest, const void *src, size_t n);
  其中:n为指定的拷贝的字节长度。
  2定义
  2-1 从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中.
  2-2 注意:source和destin都不一定是数组,任意的可读写的空间均可
  3拷贝终止条件:
  复制次数达到n
  4代码实现
  void *mymemcpy(void *dst,const void *src,unsigned int num)//没有考虑内存重叠。
  {
  assert(dst!=NULL&&src!=NULL);
  char*pdst=(char*)dst;
  const char *psrc=(const char*)src;
  while(num--)
  {
  *pdst++=*psrc++;
  }
  return dst;
  }
  /******************************************/
  思考
  /**********************************************/
  上面的memcpy()看似没有什么问题,但是当dst与src发生内存重叠时,会出现问题了。
  (这里需要说明的是,有些IDE像vs2010等已经考虑了这种情况了,所以你所调用的memcpy是我们下文要说的memmove.但是c标准没有规定一定要对memcpy进行内存重叠的考虑。所以你可能会发现有的编译环境下memcpy考虑了内存重叠,有些则没有考虑。这里我们说的是没有考虑的情况。)
  举个例子。
  char str[]="abbbb";
  memcpy(str+2,str,3);
  我们本意是将str后面的三个连续的字符拷贝到str[2]往后的三个字节里面。是说我们期待着的结果是:str[]=“ababb”;
  但是当你执行之后,会发现运行结果是str="ababa";原因很简单,内存发生了重叠了,原本的str[2]为’b’,在第一次拷贝时被str[0]给替换成了’a’了,这导致了后一次拷贝时str[2]传递给str[4]的是’a’而不是‘b’。