自学内容网 自学内容网

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


内存函数是用于 操作内存块的一组函数,它们可以对内存进行复制、移动、设置和比较等操作。这些函数主要在 <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 的值

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

希望读者们多多三连支持

小编会继续更新

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

请添加图片描述


原文地址:https://blog.csdn.net/Zero_VPN/article/details/143735190

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!