当前位置:网站首页>(作业)C语言做题:内存函数memmove、memcpy的模拟
(作业)C语言做题:内存函数memmove、memcpy的模拟
2022-07-20 14:00:00 【dfnsyyds】
0.回顾
strcpy只是做字符串copy,而memcpy和memmove不必关心任何类型数据
1.memcpy()使用:
- strncpy(char* dest, const char* src, size_t count); 两者参数很像
memcpy(void* dest, const void* src, size_t count):把源数据拷贝到dest,大小为count,返回的是目标空间起始地址,即返回无类型的void* - const放在*左边表示指针所指向内容,不能通过指针改变。 const对星和内容一起限定,指针指向内容不能改变,是一种保护。
- 使用示例:
int main()
{
int arr1[10] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int arr2[5] = {
0 };
memcpy(arr2, arr1, 20);
return 0;
}
效果:
复制的是int类型5个数字,有20个字节,所以如右侧复制了5个
1. 自写memcpy()
void* my_memcpy(void* dest, const void* src, size_t count)
{
// 断言判断dest和src输入
assert(dest&&src);
// 按长度减少不断做
while (count--)
{
assert(dest&&src);
void* ret = dest;
// 1个字节的走,所以先(char*)对dest一个字节地做,然后通过解引用,即外加*拿到内容
*(char*)dest = *(char*)src;
// 然后挪动一个字节 但void的dest不能直接++,要一个字节一个字节做,所以用char*,
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[5] = {
0 };
my_memcpy(arr2, arr1, 20);
return 0;
}
思路:1.因为memcpy可以复制任何类型的变量,所以必须用void无类型的指针dest和src
2. 写的时候,一个字节一个字节地做
3. 外层循环字节数–,内层先对src强转char*,因为char是一个字节,然后把用星解引用的内容给了强转成char后的dest,最后解引用。然后是两者+1,但是+也得先转为char*,这样才能一个字节一个字节+。
4.最后需要返回dest,即被更改的dest起始,但是经过内层dest已经变了,所以开始的时候先存起来。
2.memmove():重叠内存拷贝
memcpy只适合拷贝两个不同的元素,不可做重叠内层拷贝。
如下图对自己拷贝5个,从位置3起始开,结果得到arr1如右结果,1 2 1 2 1 ,为什么呢?
因为之前的源码写法是从头往后拷贝,而从arr1的第三个开始拷贝,arr1的第一个会覆盖arr1第3个值,随后给6位置拷贝3时,已经丢失了,那么这个时候需要memove()
void* memmove(void* dest, const void *src, size_t count);
memmove做连续地址上的移位。如何复制不会被覆盖,主要是因为重叠,需要考虑从前往后还是从后往前。
如果dest在前而src在后,则从src的头开始往后复制,反之从src的尾->头。
实现
void* my_memmove(void* dest, const void* src, size_t count)
{
assert(dest && src);
char* ret = dest;
//如果dest在前而src在后,则从src的头开始往后复制,反之从src的尾->头。
// 主要要小心覆盖
if (dest<src)
{
// 前->后
while (count--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest+1;
src = (char*)src+1;
}
}
else {
while (count--)
{
// count经过判断已经是19了,src+count是第20元素的起始地址
*((char*) dest+count) = *((char*)src + count); // count不断在减少,所以能做完。
}
}
return ret;
}
思路
memmove主要是防止同一段变量地址拷贝的覆盖,所以区分src从头到尾复制和src从尾到头,具体解释看上面吧
结果:
边栏推荐
- 如何实现一个状态机?
- C语言中长度为零的数组详解 (1)【文章结尾有资料】
- 关于let变量提升的问题
- App automated test -1 Appium installation and configuration
- WireShark 抓包及快速定位数据包技巧
- Looking back from the eight queens problem (violent enumeration)
- windows server2012 r2中搭建PHP
- 敏实集团IPO被终止:曾拟募资65亿 秦荣华曾遭法院处罚
- 【等保常见问题解答】等保测评机构能帮忙做等保整改吗?
- JS common replace () method cases
猜你喜欢
游戏合作伙伴专题:BreederDAO 与 MonkeyLeague 的合作拉开序幕
安装 scoop和lux (原annie)
[server data recovery] a data recovery case in which the storage raid6 array was paralyzed due to power failure
Netease game Flink SQL platform practice
加入 MotoGP Monster Energy 英伦大奖赛!
Online communication - knowledge driven multi strategy and multi-modal question and answer Technology Practice (Qingyuan talk, issue 22, Wang haofen)
Scala advanced (VII): collection content summary (Part 1)
敏实集团IPO被终止:曾拟募资65亿 秦荣华曾遭法院处罚
记录封装组件和项目中防抖的使用
C语言中长度为零的数组详解 (1)【文章结尾有资料】
随机推荐
Dependency injection
7.16 - 每日一题 - 408
Go deep into the use skills of go map
Opportunities to segment industries
JS determines whether each key in the object has a value
关于果子的思考
7.19 - 每日一题 - 408
Example analysis of path finding problem (violence solving method)
细分行业的机会
Magic of time
Clip based pornographic image recognition; The latest ml course collection of tubing; Write shell pipes interactively; Incremental perception data set of robot warehouse environment; Latest AI paper |
leetcode:730. 统计可以生成多少个不同回文子序列
根据yolo txt标签数据画标注框
敏实集团IPO被终止:曾拟募资65亿 秦荣华曾遭法院处罚
多进程中fork
[vulnerability recurrence] Apache log4j2 Remote Code Execution Vulnerability
II Uni app page foundation [new file specification, page life cycle]
什么是IFTMCS指示合同状态报文?
Sorting and retrieval (merging / quick sorting / bisection)
关于游泳的思考