1.memcpy
它可以理解为memory + copy的组合,memory有记忆的意思,这里指的是内存,copy是拷贝,这个函数是针对内存块进行拷贝的
函数原型
void* memcpy(void* destination,const void* source, size_t num);
从source位置开始,向后num个数据拷贝到destination中,它与字符串的strcopy类似,但是遇到'\0'不会停下来,同时,两者的内存不能重叠
我们先来写代码使用一下爱这个函数吧
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[20] = { 0 };
my_memcpy(arr2, arr1, 20); //字节的长度
int i = 0;
for (i = 0; i < 20; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
在这个代码中,我们将arr1的内容拷贝到了arr2中,拷贝了20个字节,也就是5个int类型的数字,一定要注意是字节的拷贝,这是运行结果
现在,我们来模拟实现这个函数吧
void* my_memcpy(void* dest, void* src, size_t num)
{
int i = 0;
void* ret = dest;
assert(dest && src);
/*for (i = 0; i < num; i++)
{
*((char*)dest + i) = *((char*)src + i);
}*/
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
那如果我们想实现在一个数组内进行操作,比如我想操作arr1数组,把第二个数字开始更改,进行拷贝,如果我们写出如下的代码,可能运行结果与我们考虑的就不同了
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
my_memcpy((arr1+2), arr1, 20); //字节的长度
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
我们想要得到的是 1,2,1,2,3,4,5,8,9,10,但实际结果是:
实际上,这是因为memcpy是不能有内存重叠的,这样我们先更改了,然后再访问,因此出现了很多个1,2
当然,VS有保护机制,我们现在也可以使用memcpy来实现了,但理论上 是不行的
2.memmove
memmove和memcopy的差别是memmove函数处理源内存块和目标内存块是可以重叠的,最后返回目标空间的起始地址
函数原型
void* memmeove(void* dest, const void* src, size_t num)
现在,我们可以运用这个函数来实现了
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
memmove((arr + 2), arr, 5*sizeof(int));
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
现在,我们来看看结果是否和我们想要的一样?
那么,我们是否可以尝试进行模拟这个函数呢?
第一种方法,我们在函数中再创建一个数组,将内容拷贝过去,然后再进行
那我们是否可以不创建新数组,来实现这个函数呢?
事实上,我们可以根据dest和scr的位置来判断
当dest在src之前时,我们从前向后进行拷贝,当dest在src后面时,我们从后向前进行拷贝,因此,我们可以写出以下的代码
void* my_memmeove(void* dest, const void* src, size_t num)
{
assert(dest && src);
void* ret = dest;
if (dest < src)
{
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else
{
while (num--)
{
*((char*)dest + num) = *((char*)src + num);
}
}
return ret;
}
3.memset
是用来完成内存设置的
函数原型:
void * memset(void* ptr,int vulue,size_t num);
ptr代表要填充的内存块的位置,vulue是设置的值,num是填充几个字节的位置
现在我们来使用这个函数吧!
int main()
{
char arr[] = "hello world";
memset(arr, 'x', 5);
printf("%s ", arr);
return 0;
}
这里,我们将前五个字符变成了x,结果如下:
当然,也不仅限于字符串函数,整形函数也可以,但是我们需要注意,这里是把所有的字节转换,而int类型占据4个字节,应该注意如何来运用
4.memcmp
完成内存块的比较
函数原型
int memcmp(const void* ptr1, const void* ptr2, size_t num);
从ptr1与ptr2开始num个字节进行比较,返回值是数字,前者大返回大于0的,后者大返回小于0的,相等返回0
我们来使用这个函数吧
int main()
{
int arr1[] = { 1,2,3,4,5,6,7 };
int arr2[] = { 1,2,3,4,8,8,8 };
int ret = memcmp(arr1, arr2, 16);
printf("%d ", ret);
return 0;
}
结果是这样
感谢您的观看