本篇文章重点介绍内存函数的使用及其模拟函数的实现。
memcpy
内存拷贝函数,根据内存块再拷贝
参数1为目的地位置,参数二为拷贝源位置,参数三为要拷贝数据的大小(单位为字节)
eg:
此编码中目的位置为arr1起始位置为arr2,要拷贝的数据大小为20个字节。
(因为要拷贝20个字节,且arr1和arr2都为整型元素(一个整形元素的大小为4字节,所以20/4=5)所以要拷贝五个元素给arr2)。如图arr2数组前五个元素变成了1 2 3 4 5.
注意:因为memcpy前两个参数都为void*空指针类型,所以不存在类型限制,可以传任何类型。
模拟实现memecpy函数:
参考代码:
#include<stdio.h>
#include<assert.h>
void* my_memcpy(void *dest,const void *src,size_t num)//因为不知道函数的参数的类型所以定义void*(即不存在类型限制),size_t:因为所传参数不为负数所以定义为无符号类型
{void* ret=dest;//因为dest已经发生改变所以要先赋值,在返回ret
assert(dest && src);//因为要对dest和src解引用所以要断言
//因为dest和src都为空指针类型没有具体类型不能直接解引用和++、——,所以要强制类型转换
while(num--)//要拷贝的次数
{
*(char*)dest=*(char*)src;//因为不知道具体类型所以强制类型转换为char*类型
dest=(char*)dest+1;
src=(char*)src+1;
}
return ret;
}//返回的为dest的位置所以定义为void*返回类型函数。
int main()
{
int arr1[10]={1,2,3,4,5,6,7,8,9,10};
int arr2[10]={0};
return 0;
}
此模拟函数不能用*(char*)dest++;
++的时候(强制类型转换)效果已经过去且后缀++优先级>(强制类型转换)
eg:
模拟函数注意点:
memcpy拷贝自己的时候:(此过程是实现在模拟memcpy函数中)
eg:
图的修改:此时参数为(arr1+2,arr1)
要把12345拷贝到34567上(拷贝完为12123458910)
结果:
12121218910
原因:
函数拷贝的时候内存重叠;
开始把1拷贝给3,3变成了;,把2拷贝给4,4变成了2;再把3拷贝给5是,此时3已经变成了1所以拷贝过去的为1依次类推所以结果为1 2 1 2 1 2 1 8 9 10
总结:
出现拷贝内存空间重叠时无发得到拷贝结果,此时引出了memmove
memmove:(内存拷贝,可拷贝内存重叠的情况)
类似的memcpy区别只在于能拷贝得到重复时想要的结果
所以我们直接来实现模拟momemove函数
模拟memmove函数:
参考代码:
#include<srido.h>
#include<assert.h>
my_memmove(void*dest,void*src,size_t num)
{ void*ret=dest;
assert(dest && src);
if(dest<src)
{
//前->后
while(num--)
{
*(char*)dest=*(char*)src;
dest=(char*)dest+1;
src=(char*)src+1;
}
}
else
{
//后->前
while(num--)
{//num开始为20,最初使用num后--进入while后num变为19
*((char*)dest+num )=*(*(char *)src+num);//最初char*指向dest的第一个位置,+19来到dest的最后一个字节
}
}
return ret;
}
int mian()
{
return 0;
}
图形结合:
分析什么情况下从前向后拷贝,什么情况下从后向前拷贝
从前向后:dest在src前面的时候
从后向前:dest在src后面的时候
前后都可以:dest>src+num;
代码结果:
dest+num解释:
总结:memcpy重叠也可在VS中用
memcmp:比较字节内存数据大小
最多比较num个,若前面字节已经比较出大小则中止比较
memset:内存设置函数
参数一:要设置的地址
参数二:要设置改成的数
参数三:要改的字节的大小
前四个整形(20个字节)全被改为01(1)
设置的是内存并不是元素大小。(求元素大小还需要再翻译)
但是字符数组可以等价于改变元素。
C语言之内存函数已经介绍完 希望各位看客可以点赞关注收藏,如果有什么不对的地方可以私信,会立即改正。