memcpy函数
内存拷贝函数,可以将任意类型的数据拷贝到需要的内存地址当中
函数原型:void * memcpy ( void * destination, const void * source, size_t num );
void*类型的指针可以接收包括int*,char*,short*等类型的指针,以此来保证可以操作多种类型的数据。具体实现是将source指针所指向的数据以字节为单位拷贝到destionation指针所指向的内存区域,拷贝的字节数为num。
原函数的使用方法十分简单,在这里就不讨论了,下面放上我们自己模拟实现的memcpy函数的代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void *my_memcpy(void* dest, const void* src, size_t count)
{
void* ret = dest;
while (count--)
{
*(char*)dest = *(char*)src;
dest = ++(char*)dest;
src = ++(char*)src;
}
return ret;
}
int main()
{
char str1[20] = "abcdef";
char str2[10] = "zxcvbnm";
my_memcpy(str1, str2, sizeof(str2));
printf("%s ", str1);
return 0;
}
有几点需要注意的:
①dest指针指向的内存空间必须可修改,src为常指针
②在进行拷贝时需要按照相应内存中所存储的数据类型对dest和src指针惊醒强制类型转换。
③声明中间变量:由于要返回目的指针,所以需要保留目的首地址。(此功能由上述代码中的ret指针实现)
④为了安全起见,可以在函数体内加assert(dest);assert(src);来保证指针非空。
memmove函数
函数原型:void * memmove ( void * destination, const void * source, size_t num );
大体描述与memcpy函数类同,但有一点需要注意memmove函数在使用时可能会出现内存叠加的情况,如下图所示:
dest指针和src指针所指向的位置如图所示,若此时要求移动4个字节的内存,则运行过程如下:
第一次:1→4
第二次:2→5
第三次:3→6
第四次:4→7
但是在第四次移动中,4号内存块中实际存储的是1号内存块中的数据,这显然有悖于题意,所以在模拟实现是我们更可以改用方向的移动法,即令src指向4号内存,dest指向7号内存,然后从后往前移动便不会再出现这样的问题,下面看代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
void *my_memmove(void* dest, const void*src, size_t count)
{
char*ret = (char*)dest;
if (dest <= src)
{
while (count--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else
{
dest = (char*)dest + count - 1;
src = (char*)src + count - 1;
while (count--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest - 1;
src = (char*)src - 1;
}
}
return ret;
}
int main()
{
char str1[20] = "xxxxxxxxxxxxx";
char str2[10] = "zxcvbnm";
my_memmove(str1,str2,sizeof(str2));
printf("%s\n", str1);
return 0;
}