@TOC
:star:本文将介绍 内存操作函数,及重点函数的 模拟实现。
正文开始@一个人的乐队
1.memcpy
相较于之前介绍过的strcpy
只能拷贝字符串,memcpy
可以拷贝任意类型,整型浮点型结构体类型等等都可以。
:green_heart:释
上代码感受它的使用:
#include<stdio.h>
#include<string.h>
int main()
{
int arr1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int arr2[20] = { 0 };
//拷贝的是整型数据
memcpy(arr2, arr1, sizeof(int)* 10);
int i = 0;
for (i = 0; i < 20; i++)
{
printf("%d ", arr2[i]);
}
printf("\n");
return 0;
}
:innocent:memcpy
的模拟实现my_memcpy
#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* src, size_t count)
{
assert(dest&&src);//断言
void* ret = dest;
while (count--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
int main()
{
int arr1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int arr2[20] = { 0 };
my_memcpy(arr2, arr1, sizeof(int)* 10);
int i = 0;
for (i = 0; i < 20; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
这里有几处小注意,我还是标注在代码旁:
2.memmove
:star:内存拷贝时,出现重叠现象的时候要用
memmove
:yellow_heart:引例:
若用my_memcpy
来完成有重叠的内存拷贝:
#include<stdio.h>
void* my_memcpy(void* dest, const void* src, size_t count)
{
assert(dest&&src);//断言
void* ret = dest;
while (count--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
int main()
{
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//这里用的是我刚刚自己模拟实现的函数
my_memcpy(arr+2, arr, sizeof(int)* 4);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
发现运行结果与预期不符:
:snowflake:这种情况下,可以从源字符串的末尾下手,从后向前一个一个字节拷:
:innocent: 模拟实现--- :snowflake:思路 + :snowflake:代码
根据src
与dest
的位置关系的不同情况,有不同的拷贝方式:
:snowflake:情况一
:snowflake:情况二
:snowflake:情况三: 没有重叠内存空间,爱咋拷咋拷
那么后两种情况可以合并,都采用从源数据的末尾下手,从后往前拷。
#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest, const void* src, size_t count)
{
assert(dest&&src);
void* ret = dest;
if (dest < src)
{
//前-->后
while (count--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else
{
//后-->前
while (count--)
{
*((char*)dest + count) = *((char*)src + count);
}
}
return ret;
}
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
my_memmove(arr+2, arr , 16);
//my_memmove(arr, arr+2, 16);
return 0;
}
还是把几个要注意的点标注在代码旁:
调试:
注
拉回到最开始的引例,小边采取了my_memcpy,而没有使用库函数memcpy,是因为vs的memcpy很nb,也可以实现内存重叠的拷贝。
相当于我让你考60分,结果你考了100分,不管怎样,只要完成了内存不重叠的拷贝就算完成任务。
:blue_heart:将来,最好还是,该用memcpy
时用memcpy,该用memmove
时用memmove.
3.memcmp
:star: 内存比较函数(一个字节一个字节比较)
:green_heart:释
上代码感受它的使用:
#include<stdio.h>
#include<string.h>
int main()
{
int arr1[] = { 1, 2, 3, 4, 5 };
int arr2[] = { 1, 2, 3, 6, 6 };
int ret = memcmp(arr1, arr2, 13);
printf("%d\n", ret);
return 0;
}