memcpy的用法总结

1.函数原型:
extern void *memcpy(void *dest, void *src, unsigned int count);

用法:#include <string.h>

功能:由src所指内存区域复制count个字节到dest所指内存区域。

说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。

例子:

    // memcpy.c
  
    #include<stdio.h>

  #include<string.h>

  int main()

  {

  char*s="Golden Global View";

  chard[20];

  clrscr();

  memcpy(d,s,strlen(s));

  d[strlen(s)]='';//因为从d[0]开始复制,总长度为strlen(s),d[strlen(s)]置为结束符

  printf("%s",d);

  getchar();

  return0;

  }

注意:
1.source和destin所指内存区域不能重叠,函数返回指向destin的指针。

2.与strcpy相比,memcpy并不是遇到''就结束,而是一定会拷贝完n个字节。

memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;

例:

char a[100], b[50];

memcpy(b, a,sizeof(b)); //注意如用sizeof(a),会造成b的内存地址溢出。

strcpy就只能拷贝字符串了,它遇到''就结束拷贝;例:

char a[100], b[50];

strcpy(a,b);

3.如果目标数组destin本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。如果要追加数据,则每次执行memcpy后,要将目标数组地址增加到你要追加数据的地址。

  //注意,source和destin都不一定是数组,任意的可读写的空间均可。
  

程序例子

example1:

作用:将s中的字符串复制到字符数组d中。

 

    //memcpy.c

  #include<stdio.h>

  #include<string.h>

  int main()

  {

  char*s="Golden Global View";

  chard[20];

  clrscr();

  memcpy(d,s,strlen(s));

  d[strlen(s)]='';//因为从d[0]开始复制,总长度为strlen(s),d[strlen(s)]置为结束符

  printf("%s",d);

  getchar();

  return0;

  }

输出结果:

Golden Global View

example2:

作用:将s中第14个字符开始的4个连续字符复制到d中。(从0开始)

  

#include<string.h>

  int main()

  {

  char*s="Golden Global View";

  chard[20];

  memcpy(d,s+14,4);//从第14个字符(V)开始复制,连续复制4个字符(View)

  //memcpy(d,s+14*sizeof(char),4*sizeof(char));也可

  d[4]='';

  printf("%s",d);

  getchar();

  return0;

  }

输出结果:

View

example3:

作用:复制后覆盖原有部分数据

  #include<stdio.h>

  #include<string.h>

  int main(void)

  {

  charsrc[] = "******************************";

  chardest[] = "abcdefghijlkmnopqrstuvwxyz0123as6";

  printf("destinationbefore memcpy: %s
", dest);

  memcpy(dest,src, strlen(src));

  printf("destinationafter memcpy: %s
", dest);

  return0;

  }

输出结果:

destinationbefore memcpy:abcdefghijlkmnopqrstuvwxyz0123as6

destinationafter memcpy: ******************************as6

另外,可以拷贝任何类型的对象,因为函数的参数类型是void *(未定义类型指针),也就是说传进去的实参可以是int *,short *,char *等等,
但是由于函数拷贝的过程是一个字节一个字节的拷贝的,所以实际操作的时候要把void *强制转化为char *,这样在指针加的时候才会保证每次加一个字节。

函数源代码实现:

void *memcpy1(void *desc,const void * src,size_t size)
{
 if((desc == NULL) && (src == NULL))
 {
  return NULL;
 }
 unsigned char *desc1 = (unsigned char*)desc;
 unsigned char *src1 = (unsigned char*)src;
 while(size-- >0)
 {
  *desc1 = *src1;
  desc1++;
  src1++;
 }
 return desc;
}

int _tmain(int argc, _TCHAR* argv[])
{
 int dest[2] = {0};
 const char src[5] = "1234";
 //printf(src);
 memcpy1(dest,src,sizeof(src));
 //*(dest+5) = '/0';
 printf((char *)dest);
 int m = -1;
 return 0;
}

(1)void* 一定要返回一个值(指针),这个和void不太一样!
(2)首先要判断指针的值不能为空,desc为空的话肯定不能拷贝内存空间,src为空相当于没有拷贝;所以之间return掉;
(3)""空串是指内容为0,NULL是0,不是串;两个不等价;
(4)int dest[2] = {0};这是对int 类型的数组初始化的方法;如果是char类型,就用char a[5] = "1234"; 注意数组下标要多于实际看到的字符数,因为还有''
(5)printf((char *)dest);这句话,是把 char 类型 src 传到 int 类型的 dest的内存强制转化成char类型,然后打印出来;
因为直接看int类型的dest是看不到里面的内容的;因为有unsigned char *desc1 = (unsigned char *)desc;所以字符可以传到dest里面保存起来,dest所指向的内存长度4个字节,强制转化为char 就是把四个字节分成一个一个的字节,这样就可以看到一个个字符了,如果定义成char dest[5] = "1234";就不用转化;
(6)memcpy1(dest,src,sizeof(src));注意里面的sizeof(src),这个是包括字符串的结束符'/0'的;所以不用担心printf(dest);
但是如果用memcpy1(dest,src,4);没有'/0'就要 *(dest+5) = '/0';这样保证是一个完整的字符串;
(7)如果初始化的时候:

char dest[1024] = "12345666";//{0};
const char src[5] = "3333";

那么拷贝的时候,如果用memcpy1(dest,src,sizeof(src));则printf(dest);出来是3333
如果memcpy1(dest,src,4);则printf(dest);出来是33335666;因为上面的sizeof(src),包含'/0',所以拷贝过去的字符串以'/0'结束,就只有3333,而如果传4个字符,'/0'是第五个字符,那就遇到dest[1024] 的'/0'结束,所以是33335666
字符串的''问题一定要注意啊!!!

更多参考

原文地址:https://www.cnblogs.com/ZY-Dream/p/10052766.html