【内存操作函数】
字符串操作函数中有一个strcpy的函数,它可以拷贝字符类型,那么有没有不关心类型的函数呢?这个,当然是有滴,大师们早就将他们写到库里面了。
1.memcpy() 用来复制内存,其原型为:
void * memcpy ( void * dest, const void * src, size_t num );
memcpy() 会复制 src 所指的内存内容的前 num 个字节到 dest 所指的内存地址上。
memcpy() 并不关心被复制的数据类型,也就是说它可以操作任意类型,只是逐字节地进行复制,这给函数的使用带来了很大的灵活性,可以面向任何数据类型进行复制。
需要注意的是:
>>1.dest 指针要分配足够的空间,也即大于等于 num 字节的空间。如果没有分配空间,会出现断错误。
>>2.dest 和 src 所指的内存空间不能重叠(如果发生了重叠,使用 memmove()会更加安全)。
与 strcpy() 不同的是,memcpy() 会完整的复制 num 个字节,不会因为遇到“\0”而结束。
【返回值】返回指向 dest 的指针。注意返回的指针类型是 void,使用时一般要进行强制类型转换。
【函数实现】
#include <stdio.h> #include <string.h> #define MAX 20 void* my_memcpy(void *dest,const void *src,size_t count) { int *buf1=(int *)dest; int *buf2=(int *)src; int *pret=(int *)dest; while (count--) { *buf1=*buf2; buf1++; buf2++; } return pret; } int main() { int arr[MAX]={0}; int brr[5]={1,2,3,4,5}; int size=sizeof(brr)/sizeof(brr[0]); int i=0; my_memcpy(arr,brr,size); for (i=0;i<MAX;i++) { printf("%d ",arr[i]); } printf("\n"); return 0; }
结果:
这个就将原数组中的0一个不漏的打印出来了,好神奇_^_^_
有了这个函数,就解决了一部分拷贝的问题,为什么说一部分呢,接下来,听我慢慢道来。这个时候,我有一个问题,如果我给定一个数组arr[10]={1,2,3,4,5,6,7,8,9,10};我想把它的{5,6,7,8}拷贝到{7,8,9,10}上去最后打印出数组arr结果应该是{1,2,3,4,5,6,5,6,7,8};接下来看代码实现:
#include <stdio.h> void* my_memcpy(void *dest,const void *src,size_t count) { int *buf1=(int *)dest; int *buf2=(int *)src; int *p=(int *)dest; while (count--) { *buf1=*buf2; buf1++; buf2++; } return p; } int main() { int arr[10]={1,2,3,4,5,6,7,8,9,10}; int i=0; my_memcpy(arr+6,arr+4,16); for (i=0;i<10;i++) { printf("%d ",arr[i]); } printf("\n"); return 0; }
结果:
这个结果怎么和预先预测的结果不一样呢_~~_这就是出现上面注意的第二点dest 和 src 所指的内存空间不能重叠,如果出现重叠,就会出现想不到的问题。
所以此时就要用一个memmove()的函数,他很好的处理了这个问题。
2.memmove() 用来复制内存内容,其原型为:
void * memmove(void *dest, const void *src, size_t num);
memmove() 与 memcpy() 类似都是用来复制 src 所指的内存内容前 num 个字节到 dest 所指的地址上。不同的是,memmove() 更为灵活,当src 和 dest 所指的内存区域重叠时,memmove() 仍然可以正确的处理.同样是上面的问题,具体看下它的实现:
【函数实现】
#include <stdio.h> void *my_memmove(void *dest,const void *src,size_t count) { int *buf1=(int *)dest; int *buf2=(int *)src; int *p=(int *)dest; if (buf1>buf2&&buf1<buf2+count) { while (count--) { *(buf1+count)=*(buf2+count); } } else { while (count--) { *buf1++=*buf2++; } } return p; } int main() { int arr[10]={1,2,3,4,5,6,7,8,9,10}; int i=0; my_memmove(arr+6,arr+4,16); for (i=0;i<10;i++) { printf("%d ",arr[i]); } printf("\n"); return 0; }
结果:
这个结果就和预先猜想的一样了,为什么会一样呢?因为当它处理有重叠时,它在拷贝时,会从后往前复制,就不会干扰到源了,所以结果正确。不重叠时,仍然和memcpy()一样,但效率能比memcpy()
低,因为它在复制之前还要进行判断_^_._^_