void * memcpy ( void * destination, const void * source, size_t num );
1.函数作用:将source指向空间的前num个字节的数据拷贝到destination里面
2.不关心’\0’,不会因为’\0’而停下,它只关心拷贝多少个字节,即num。
3.要拷贝的内容和被拷贝的空间不可以重叠
4.相比较于strcpy函数,memcpy函数可以拷贝可以更多类型数据,如字符串、整型数组、结构体
5.要引用头文件#include
6.返回值是目标空间首元素地址
#include
void* my_memcpy(void* dest, const void* src, size_t num)
{
void* ret = dest;
assert(dest && src);
while (num--)//num次
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
my_memcpy(arr2, arr1, 4 * 5);
int i = 0;
for (i = 0;i < 10;i++)
{
printf("%d ", arr2[i]);
}
}
运行结果:
注:
1.为保证不对空指针进行加减解引用操作,要用到assert
2.为保证不通过指针修改被复制的内容,用const修饰源头内容空间地址
3.指针强制转化只能使用一次,当下用完当下失效,不可以写成(char ∗ * ∗)++或(char ∗ * ∗)–;++(char ∗ * ∗)或–(char ∗ * ∗)在某些编译器下不能这样写
按照memcpy中的例子,当我想把arr1中的12345拷贝到34567位置上,即同一数组中的A部分拷贝到B部分,A、B两部分有重叠会出现什么?
预期效果:1 2 1 2 3 4 5 8 9 10
实际效果:1 2 1 2 1 2 1 2 1 2
memcpy函数只能拷贝不重叠、不相关的两个部分,想要实现重叠部分的拷贝,需要memmove函数
void * memmove ( void * destination, const void * source, size_t num );
和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
用memmove函数实现重叠部分复制
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(arr1 + 2, arr1, 5 * 4);
int i = 0;
for (i = 0;i < sizeof(arr1)/sizeof(arr1[0]);i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
(1)思路一:创建一个arr2来存放需要被拷贝的内容
缺点:浪费空间
(2)思路二:在同一空间内操作,将同一数组内相同大小且重叠的两部分A复制给B
情况一:A在前B在后,把A拷贝到B上(橙A蓝B)
A在前B在后时,指针从后往前依次赋值,被复制的内容不会被覆盖。此时指针destination减指针source>0
情况二:A在后B在前,把A拷贝到B上(橙A蓝B)
A在后B在前时,指针从前往后依次赋值,被复制的内容不会被覆盖。此时指针destination减指针source<0
1.指针destination减指针source>0:从后往前拷贝
2.指针destination减指针source<0:从前往后拷贝
void* my_memmove(void* dest, void* src, size_t num)
{
void* ret = dest;
assert(dest && src);
if (dest < src)//dest-src<0,从前往后
{
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
if (dest > src)//dest-src>0,从后往前
{
while (num--)
{
*((char*)dest + num) = *((char*)src + num);
}
}
return ret;
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(arr+2, arr, 5 * 4);
int i = 0;
for (i = 0;i < sizeof(arr) / sizeof(arr[0]);i++)
{
printf("%d ", arr[i]);
}
}
运行结果:
目标空间地址为arr,源内容地址为arr+2时,主函数为:
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(arr, arr+2, 5 * 4);
int i = 0;
for (i = 0;i < sizeof(arr) / sizeof(arr[0]);i++)
{
printf("%d ", arr[i]);
}
}
运行结果:
注:
①其实在VS上memcpy可以实现重叠拷贝,但别的编译器上不一定,VS是个优等生,把没要求的也完成了,其他编译器不一定能实现
②memmove也可以实现不重叠部分的拷贝,也具有memcpy的功能
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
功能:比较从ptr1和ptr2指针开始的num个字节
返回值:
用memcmp比较两字符串
#include
#include
int main()
{
char buffer1[] = "DWgaOtP12df0";
char buffer2[] = "DWGAOTP12DF0";
int n;
n = memcmp(buffer1, buffer2, sizeof(buffer1));
if (n > 0) printf("'%s' 大于 '%s'.\n", buffer1, buffer2);
else if (n < 0) printf("'%s' 小于 '%s'.\n", buffer1, buffer2);
else printf("'%s' 等于 '%s'.\n", buffer1, buffer2);
return 0;
}
运行结果:
注:第三个参数size_t num是比较的字节数:
①前9个字节大小相同,返回0
②arr1在第10个字节中存的是00,arr2存的是01,arr2>arr1,返回-1