目录
一.memcpy函数
1.介绍
void * memcpy ( void * destination, const void * source, size_t num );
为保证函数的泛用性,函数类型,参数类型均为无符号型。
功能:
将用户输入字节数的值从源的位置直接复制到目标指向的内存块中。但对于重叠的数据复制本函数会出现错误。
1.从arr1复制一定数量的数字到arr2中
#include<stdio.h>
#include<string.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
memcpy(arr2, arr1, 5);
for (int i = 0; i != '\n'; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
2.arr1中的重叠复制,5,6,7,8,9五个数字复制到3,4,5,6,7的所在位置上。
#include<stdio.h>
#include<string.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
memcpy(arr1+2, arr1+4, 5);
for (int i = 0; i != '\n'; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
结果并不是理想中的1,2,5,6,7,8,9,8,9,10的结果。原因是在复制过程中,导致数据丢失。 所以memcpy函数不适合重叠复制。
2.模拟实现
基本要求:
1.保证函数的泛用性
2.实现给定地址之间的字符复制
实现:
1.main函数书写
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
my_memcpy(arr2, arr1, 10*4);
for (int i = 0; i < 10; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
2.模拟函数my_memcpy声明
void* my_memcpy(void* dest, const void* str, size_t num);
3.my_memcpy函数实现
a.因为函数参数类型均为无符号型,所以需要强制类型转换,转化为char类型效果是最好的。
复制过程中要保证原数据不发生变化,所以需要用const(不能通过该指针修改所指向的数据)修饰。
b.函数需要返回目标数组的地址,但在后续的变换中目标数组地址会向后移动。所以我们需要一个指针来存储最开始的地址值。
c.int为4字节,char为1字节。移动一个整形数据,需要循环四次。所以给需要给复制数据个数乘以四,即可解决循环问题。
void* my_memcpy(void* dest, const void* str, size_t num)
{
assert(dest && str);
//assert对传进来的指针是否为空指针进行检测
// 如果非空指针不进行任何操作
// 如果是空指针就捕捉到这种错误
// 并打印出错误信息,终止程序执行。
char* ret = (char*)dest;
while (num--)
{
*(char*)dest = *(char*)str;
dest = (char*)dest + 1;
str = (char*)str + 1;
}
return ret;
}
4.完整代码
#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* str, size_t num)
{
assert(dest && str);
//assert对传进来的指针是否为空指针进行检测
// 如果非空指针不进行任何操作
// 如果是空指针就捕捉到这种错误
// 并打印出错误信息,终止程序执行。
char* ret = (char*)dest;
while (num--)
{
*(char*)dest = *(char*)str;
dest = (char*)dest + 1;
str = (char*)str + 1;
}
return ret;
}
void* my_memcpy(void* dest, const void* str, size_t num);
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
my_memcpy(arr2, arr1, 10*4);
for (int i = 0; i < 10; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
二.memmove函数
1.介绍
void * memmove ( void * destination, const void * source, size_t num );
为保证函数的泛用性,函数类型,参数类型均为无符号型。
功能
将一定数量的值从源的位置复制到目标指向的内存块中。复制就像使用了中间缓冲区一样,允许目标和源重叠。
1.从arr1+4开始向后五个数复制到以arr1+2开始的位置。
#include<stdio.h>
#include<string.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
//1,2,5,6,7,8,9,8,9,10
int arr2[] = { 0 };
int n;
scanf("%d", &n);
menmove(arr1 + 2, arr1 + 4, n * 4);
for (int i = 0; i != '\n'; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
2.结果
2.模拟实现
基本要求
a.因为函数参数类型均为无符号型,所以需要强制类型转换,转化为char类型效果是最好的。
复制过程中要保证原数据不发生变化,所以需要用const(不能通过该指针修改所指向的数据)修饰。
b.函数需要返回目标数组的地址,但在后续的变换中目标数组地址会向后移动。所以我们需要一个指针来存储最开始的地址值。
c.int为4字节,char为1字节。移动一个整形数据,需要循环四次。所以给需要给复制数据个数乘以四,即可解决循环问题。
d.memmove函数是如何实现重叠复制的呢?这跟源地址和目标地址的前后有关系。
分析:
实现
1.main函数
#include<stdio.h>
#include<string.h>
#include<assert.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
//1,2,5,6,7,8,9,8,9,10
int arr2[] = { 0 };
my_menmove(arr1 + 2, arr1 + 4, 5 * 4);
for (int i = 0; i != '\n'; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
2.函数声明
void* my_menmove(void* dest,const void* str, size_t num);
3.my_memmove函数
void* my_menmove(void* dest,const void* str, size_t num)
{
assert(dest && str);
char* ret = (char*)dest;
if (dest < str)//前—>后
{
while (num--)
{
*(char*)dest = *(char*)str;
dest = (char*)dest + 1;
str = (char*)str + 1;
}
}
else//后—>前
{
while (num--)
{
*((char*)dest + num) = *((char*)str + num);
//加num,当num=20,经过--变成19。此时dest和str经过强制转化均为1
//加19刚好满20,指向复制数字个数的最后一个
}
}
return ret;
}
4.完整代码
#include<assert.h>
#include<string.h>
#include<stdio.h>
void* my_menmove(void* dest,const void* str, size_t num)
{
assert(dest && str);
char* ret = (char*)dest;
if (dest < str)//前—>后
{
while (num--)
{
*(char*)dest = *(char*)str;
dest = (char*)dest + 1;
str = (char*)str + 1;
}
}
else//后—>前
{
while (num--)
{
*((char*)dest + num) = *((char*)str + num);
}
}
return ret;
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
//1,2,5,6,7,8,9,8,9,10
int arr2[] = { 0 };
my_menmove(arr1 + 2, arr1 + 4, 5 * 4);
for (int i = 0; i != '\n'; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
你的关注、点赞,是我写文章 动力。
最后,谢谢观看!