概述
什么是memcpy
**C 库函数 void *memcpy(void str1, const void str2, size_t n) 从存储区 str2 复制 n 个字节到存储区 str1
这是memcpy()函数的声明
void *memcpy(void *str1, const void *str2, size_t n)
参数
- str1 – 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
- str2 – 指向要复制的数据源,类型强制转换为 void* 指针。
- n – 要被复制的字节数。
实现my_memcpy
void* my_memcpy(void* buf1, void* buf2, size_t num)
{
assert(buf1); //当buf1为空指针的时候显示错误信息,并且中止程序
assert(buf2);
void* ret = buf1; //定义一个void*变量记录buf1的初始地址
while (num--) //这段循环就是逐字节复制,将buf2的地址赋给buf1
{
*((char*)buf1) = *((char*)buf2);
buf1 = (char*)buf1 + 1; //因为空指针不能进行自增自减操作,所以先转成char*指针,然后进行自增。
buf2 = (char*)buf2 + 1; //因为是地址赋值,所以必须得是逐字节,所以转成char*类型。
}
return ret; //返回buf1的初始地址
}
void test05()
{
char arr[20] = "zxc";
char arr2[] = "abc";
char* tmp = (char*)my_memcpy(arr, arr2, 3); //因为返回的是个void*,所以必须强转成(char*)
printf("%s", tmp); //结果为abc
}
memcpy有一种特殊情况
void*的指针变量
void*的指针变量就是一个什么都能接收的指针,用户不可能就只传特定的一个指针变量给你,就像你写个
**void* my_memcpy(int* buf1, int* buf2, size_t num)**
这里面写的是int指针,那么用户想传个char或者结构体指针变量呢,难道你还重写一个吗?所以这时候就要用到void*指针,什么都可以接收,可以在函数体内强转成任何类型的指针,非常好用,具体使用场景可以看看qsort()函数的模拟实现,这里就不多讲了。
什么是memmove
**C 库函数 void *memmove(void str1, const void str2, size_t n) 从 str2 复制 n 个字符到 str1,但是在重叠内存块这方面,memmove() 是比 memcpy() 更安全的方法。如果目标区域和源区域有重叠的话,memmove() 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,复制后源区域的内容会被更改。如果目标区域与源区域没有重叠,则和 memcpy() 函数功能相同。
这是memmove()函数的声明
void *memmove(void *str1, const void *str2, size_t n)
参数
- str1 – 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
- str2 – 指向要复制的数据源,类型强制转换为 void* 指针。
- n – 要被复制的字节数。
实现my_memcpy
void* my_memmove(void* buf1, const void* buf2, size_t num)
{
assert(buf1);
assert(buf2);
void* ret = buf1;
if (buf1 < buf2)
{
while (num--)
{
*((char*)buf1) = *((char*)buf2);
buf1 = (char*)buf1 + 1;
buf2 = (char*)buf2 + 1;
}
return ret;
}
else
{
while (num--)
{
*((char*)buf1 + num) = *((char*)buf2 + num);
}
}
return ret;
}
void test05()
{
int arr[] = { 1,2,3,4,5,6,7,8,9 };
char arr2[] = "abc";
my_memmove(arr + 5, arr + 3, 16);
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d ", arr[i]);
}
}
memmove其实才是真正的memcpy,我先来解释一下这段代码
if (buf1 < buf2)
{
while (num--)
{
*((char*)buf1) = *((char*)buf2);
buf1 = (char*)buf1 + 1;
buf2 = (char*)buf2 + 1;
}
return ret;
}
else
{
while (num--)
{
*((char*)buf1 + num) = *((char*)buf2 + num);
}
}
return ret;
memmove才是真男人
最后
以上就是机智人生为你收集整理的带你手写memcpy和memmove的全部内容,希望文章能够帮你解决带你手写memcpy和memmove所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复