关于我、重生到500年前凭借C语言改变世界科技vlog.18——内存函数
文章目录
- 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 的值
以上就是主要使用的内存函数,过几天就参加全国计挑了,希望可以拿个奖,没拿到就当练手了吧,毕竟竞赛经验更重要🤩