原文:http://liangbing8612.blog.51cto.com/2633208/696753
memcpy函数较memmove相比,存在的不足是没有考虑到目的地址与源地址相重合,本文对memcpy作了修改,弥补其不足。
memcpy函数的特点是:
1. 使用memcpy函数前,实参dest必须初始化,否则可能会出错,原因见2。
2. 函数原理是将void *src 强制转换为char *s,然后只负责拷贝n个字节到dest里,不负责在最后加上'\0'。
下面的代码其实是实现了memmove的功能,然后根据memcpy的参数为void*,给其分别尝试传入int*和char*,以此来掌握int*是如何转化为char*,及强制转化后是什么结果,涉及到大端和小端...等等。
- #include <stdio.h>
- #include <string.h>
- void * mymemcpy(void *dest,void *src, int n)
- {
- char *d;
- char *s;
- int i=0;
- s=(char *)src;
- d=(char *)dest;
- if(dest==NULL || src==NULL || n<0)
- return 0;
- if(d>=s && d<=s+n-1)
- {
- i=n-1;
- printf("%d\n",i);
- while(i>=0)
- {
- d[i]=s[i];
- i--;
- }
- }
- else
- {
- while(i<n)
- {
- //printf("%x ",s[i]);
- d[i]=s[i];
- //printf("i=%d %x\n",i,d[i]);
- i++;
- }
- d[i]='\0';
- }
- dest=(void *)d;
- return dest;
- }
- int main(char **argv,int argc)
- {
- //情况1
- char src[100]="helloworldhui";
- //如果是特殊情况mymemcpy(src+2,src,7);,则不可写成char *src=\'#\'"
- //char dest[100]=""; //必须初始化
- char *dest;
- dest=(char *)mymemcpy(src+2,src,7);
- printf("%s\n",dest);//*/
- //情况2
- /* int src=123456789 ; //对应十六进制:75BCD15
- int dest=0;
- //dest必须初始化,不然,如果只拷贝3个字节时,dest的第四个字节未被赋值,这样输出会出错。
- memcpy(&dest,&src,3); //只能传递参数4,不然出错
- //mymemcpy(&dest,&src,3) //则拷贝前3个字节
- printf("dest=%d %x\n",dest,dest);//*/
- //情况3
- /* int src[100]={1234,12345,123456,11234567,14,15};
- int dest[100]={0};
- int i;
- memcpy(dest,src,13); //只拷贝13个字节
- //不能保证拷贝一个完整的整数,一个元素,即如果你输入13,3*4=12,只能保证前3个整数完整拷贝,
- //到了第4个整数,只拷贝它的第一个字节,如例为7
- //mymemcpy(dest,src,13);
- for( i=0;i< 5;i++)
- printf("*%d*\n",dest[i]);//*/
- return 0;
- }
- #include <stdio.h>
- int main(void)
- {
- // int src[10]={50,61,72,83,94};
- _int64 src=123456789; //0x75BCD15,它在内存中的存放从低地址,低字节开始:15,cd,5b,7
- char *p;
- int count;
- p=(char *)(&src);
- for(count=0; count<sizeof(int);p++,count++)
- printf("第%d字节处十六进制值是: %02x\n",count,*p);
- return 0;
- }