当前位置:首页 » 《休闲阅读》 » 正文

关于我、重生到500年前凭借C语言改变世界科技vlog.18——内存函数

1 人参与  2024年11月15日 13:21  分类 : 《休闲阅读》  评论

点击全文阅读


文章目录

1. memcpy函数2. memmove函数3. memset函数4. memcmp函数希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力!
内存函数是用于 操作内存块的一组函数,它们可以对内存进行复制、移动、设置和比较等操作。这些函数主要在 <string.h> 头文件中声明,其操作对象通常是字节序列,不管这些字节代表的是字符、整数还是其他数据类型

1. memcpy函数

memcpy 主要用于将一段内存中的数据完整地复制到另一段内存中,在很多场景下都非常有用,例如在处理数组、结构体等数据结构时,从源内存地址 src 复制 n 个字节的数据到目标内存地址 destination

在这里插入图片描述

传送门:memcpy-C++参考

参数:destination-目标内存地址,它是一个 void* 类型的指针,source-源内存地址,同样是 void* 类型(不可修改),num-要复制的字节数

返回值:返回指向目标内存地址 destination 的指针

值得注意的是:函数 memcpy 从 source 的位置开始向后复制 num 个字节的数据 destination 指向的内存位置,这个函数在遇到 ‘\0’ 的时候并不会停下来,如果 source 和destination 有任何的重叠,复制的结果都是未定义的

eg

#include <stdio.h>#include <string.h>int main(){    char src[] = "Hello, World!";    char dest[20];    memcpy(dest, src, strlen(src)+1);    printf("%s\n", dest);    return 0;}

memcpy 函数将 src 数组中的字符串(包括字符串结束符 \0 )复制到 dest 数组中 strlen(src)+1 是为了把 \0 也复制过去

memcpy 的模拟实现

void* memcpy(void* dst, const void* src, size_t count){void* ret = dst;assert(dst);assert(src);/** copy from lower addresses to higher addresses*/while (count--) {*(char*)dst = *(char*)src;dst = (char*)dst + 1;src = (char*)src + 1;}return(ret);}

将dst和src先强制转换为char*类型,实现了以字节为单位的访问和赋值操作,因为 char类型在内存中占用一个字节,所以这样可以逐个字节地复制数据,而不管原始数据的类型是什么,分别将目标地址 dst 和源地址 src 向后移动一个字节的位置,以便在下一次循环中复制下一个字节的数据

2. memmove函数

memmove 和 memcpy 类似,也是从源内存地址 source 复制 num 个字节的数据到目标内存地址destination ,但是 memmove 函数能够处理源内存区域和目标内存区域重叠的情况

在这里插入图片描述

传送门:memmove-C++参考

参数:destination-目标内存地址,它是一个 void* 类型的指针,source-源内存地址,同样是 void* 类型(不可修改),num-要复制的字节数

返回值:返回指向目标内存地址 destination 的指针

值得注意的是:和 memcpy 的差别就是 memmove 函数处理的源内存块和目标内存块是可以重叠的,如果源空间和目标空间出现重叠,就得使用 memmove 函数处理

eg

#include <stdio.h>#include <string.h>int main(){    char str[] = "abcdef";    // 将字符串中的后3个字符向前移动2个位置    memmove(str + 2, str + 3, 3);    printf("%s\n", str);    return 0;}

str + 3 是源地址,str + 2 是目标地址,存在重叠部分,memmove 函数可以正确地完成复制操作,而 memcpy 函数不能完成有重叠的操作

mememove 的模拟实现

void* memmove(void* dst, const void* src, size_t count){void* ret = dst;if (dst <= src || (char*)dst >= ((char*)src + count)) {/** Non-Overlapping Buffers* copy from lower addresses to higher addresses*/while (count--) {*(char*)dst = *(char*)src;dst = (char*)dst + 1;src = (char*)src + 1;}}else {/** Overlapping Buffers* copy from higher addresses to lower addresses*/dst = (char*)dst + count - 1;src = (char*)src + count - 1;while (count--) {*(char*)dst = *(char*)src;dst = (char*)dst - 1;src = (char*)src - 1;}}return(ret);}

首先判断源内存区域和目标内存区域是否有重叠情况,然后就是分为非重叠和重叠的情况和 memcpy 模拟实现类似的操作

3. memset函数

memset 能将指定内存区域 ptr 的前 num 个字节设置为指定的值 value

在这里插入图片描述

传送门:memset-C++参考

参数:ptr-要设置的内存区域的起始地址,是 void* 类型,value-要设置的值,这个值会被转换为 unsigned char 类型后进行设置,num-要设置的字节数

返回值:返回指向设置后的内存区域 ptr 的指针

值得注意的是:设置完内容后,记得在后面加上 \0

eg

#include <stdio.h>#include <string.h>int main(){    char buffer[10];    memset(buffer, 'A', 5);    buffer[5]='\0';    printf("%s\n", buffer);    return 0;}

memset 将 buffer 数组的前 5 个字节设置为字符A,然后手动添加字符串结束符 \0 ,以便能够正确地使用 printf 输出字符串

4. memcmp函数

memcmp 用于比较两个内存区域 ptr1 和 ptr2 的前 num 个字节
在这里插入图片描述

传送门:memcmp-C++参考

参数:ptr1、ptr2-要比较的两个内存区域的起始地址,都是 const void* 类型,num-要比较的字节数

返回值
• 如果 ptr1 所指向的内存区域的前 num 个字节大于 ptr2 所指向的内存区域的前 num 个字节,返回一个大于 0 的值
• 如果 ptr1 所指向的内存区域的前 num 个字节小于 ptr2 所指向的内存区域的前 num 个字节,返回一个小于 0 的值
• 如果 ptr1 所指向的内存区域的前 num 个字节等于 ptr2 所指向的内存区域的前 num 个字节,返回 0

值得注意的是:比较从 ptr1 和 ptr2 指针指向的位置开始,向后的 num 个字节,遇到第一个不一样的比较就行了

eg

#include <stdio.h>#include <string.h>int main(){    char str1[] = "abc";    char str2[] = "abd";    int result = memcmp(str1, str2, 3);    printf("%d\n", result);    return 0;}

memcmp 比较 str1 和 str2 的前 3 个字节,因为 c 的 ASCII 码小于 d 的 ASCII 码,所以返回一个小于 0 的值

以上就是主要使用的内存函数,过几天就参加全国计挑了,希望可以拿个奖,没拿到就当练手了吧,毕竟竞赛经验更重要?

希望读者们多多三连支持

小编会继续更新

你们的鼓励就是我前进的动力!

请添加图片描述


点击全文阅读


本文链接:http://m.zhangshiyu.com/post/186535.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1