#C语言——学习攻略:探索内存函数--memcpy、memmove的使用和模拟实现,memset、memcmp函数的使用
🌟菜鸟主页:@晨非辰的主页
👀学习专栏:《C语言学习》
💪学习阶段:C语言方向初学者
⏳名言欣赏:"代码是写给人看的,顺便让机器执行。"
目录
1. memcpy函数
1.1 memcpy函数使用示范
1.2 模拟实现memecpy函数(--请看注释:字节访问、临时强转)(要会复现)
2. memmove函数
2.1 memmove函数使用示范
2.2 模拟实现memmove函数(要会复现)
3. memset函数
3.1 memset函数使用示范
3.2 使用总结
4. memcmp函数
4.1 memcmp函数使用演示
4.2 使用总结
1. memcpy函数
void* memcpy(void* destination, const void* source, size_t num);
--介绍:
--功能:
- 函数 memcpy 从 source 的位置开始向后复制 num 个字节的数据到 destination 指向的内存位置;
- 这个函数在遇到'\0'的时候不会停下来;
- 如果 source 和 destination 有任何的重叠,复制的结果都是未定义的(内存重叠的情况在 memmove中有介绍 );
- memcpy 的使用需要包含<string.h>;
--参数:
- destination:指针,指向目标空间,拷贝的数据存放在这里;
- source:指针,指向源空间,要拷贝的数据从这里来;
- num:要拷贝的数据占据的字节数;
--返回值:拷贝完成后,返回目标空间的起始地址
1.1 memcpy函数使用示范
#include <string.h>
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[20] = { 0 };memcpy(arr2, arr1, 16);for (int i = 0; i < 5; i++){printf("%d ", arr2[i]);}return 0;
}
1.2 模拟实现memecpy函数(--请看注释:字节访问、临时强转)(要会复现)
#include <string.h>
#include <assert.h>
void* my_memcpy(void* dest, const void* src, size_t num)
{//先将dest初始地址存上,防止后续操作覆盖初始地址void* ret = dest;assert(dest && src);//循环直接将字节数当条件,更简单while (num--){//因为都是void*类型,无法直接解引用,在这里进行强转//强转为char*, 是因为可以按照1字节进行访问,但是只有char*可许,其余不行*(char*)dest = *(char*)src;//强转是临时的,再次强转dest = (char*)dest + 1;src = (char*)src + 1;}return ret;
}
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[20] = { 0 };my_memcpy(arr2, arr1, 16);for (int i = 0; i < 4; i++){printf("%d ", arr2[i]);}return 0;
}
2. memmove函数
void* memmove(void* destination, const void* source, size_t num);
--介绍:
--功能:
- 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的;
- 使用需要包含<string.h>;
--参数:
- destination:指针,指向目标空间,拷贝的数据存放在这里;
- source:指针,指向源空间,要拷贝的数据从这里来;
- num:要拷贝的数据占据的字节数;
--返回值:拷贝完成后,返回目标空间的起始地址
2.1 memmove函数使用示范
#include <string.h>
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[20] = { 0 };memmove(arr2, arr1, 16);for (int i = 0; i < 4; i++){printf("%d ", arr2[i]);}return 0;
}
2.2 模拟实现memmove函数(要会复现)
#include <string.h>
#include <assert.h>
void* my_memmove(void* dest, const void* src, size_t num)
{//先将dest初始地址存上,防止后续操作覆盖初始地址void* ret = dest;assert(dest && src);//当dest在左边与src重叠,前往后进行拷贝if (dest < src){*(char*)dest = *(char*)src;//往后进行dest = (char*)dest + 1;src = (char*)src + 1;}//右边重合、没重合:后向前else{while (num--){*((char*)dest + num) = *((char*)src + num);}}return ret;
}
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };//int arr2[20] = { 0 };my_memmove(arr1 + 2, arr1, 16);for (int i = 0; i < 4; i++){printf("%d ", arr1[i]);}return 0;
}
3. memset函数
void* memset(void* ptr, int value, size_t num);
--介绍:
--功能:
- memset 函数是用来设置内存块的内容的,将内存中指定长度的空间设置为特定的内容;
- 使用需要包含<string.h>;
--参数:
- ptr:指针,指向要设置的内存空间,也就是存放了要设置的内存空间的起始地址;
- value:要设置的值,函数将会把 value 值转换成 unsigned char 的数据进行设置的。 也就是以字节为单位来设置内存块的;
- num:要设置的内存长度,单位是字节;
--返回值:
返回的是要设置的内存空间的起始地址。
3.1 memset函数使用示范
#include <string.h>
int main()
{char arr[] = "hello world";memset(arr + 2, 'x', 6);printf("%s", arr);return 0;
}
--但是注意,下面这串代码就不能实现:
int main()
{int arr1[] = { 0 };memset(arr1, 1, 40);return 0;
}
--但是可以设置为0.
3.2 使用总结
--当有一块内存空间需要设置内容的时候,就可以使用memset函数,值得注意的是memset函数对内存单元的设置是以字节为单位的。
4. memcmp函数
int memcmp(const void* ptr1, const void* ptr2, size_t num);
--介绍:
--功能:
- 比较指定的两块内存块的内容,比较从ptr1和ptr2指针指向的位置开始,向后的num个字节;
- 使用需要包含<string.h>;
--参数:
- ptr1:指针,指向一块待比较的内存块;
- ptr2:指针,指向另外一块待比较的内存块;
- num:指定的比较长度,单位是字节;
--返回值:
4.1 memcmp函数使用演示
#include <string.h>
int main()
{char arr1[] = "abcdefgh";char arr2[] = "abcdef";int ret;ret = memcmp(arr1, arr2, 5);if (ret > 0)printf(">\n");else if (ret < 0)printf("<\n");elseprintf("=");return 0;
}
4.2 使用总结
--如果要比较2块内存单元的数据的大小,可以使用 memcmp 函数,这个函数的特点就是可以指定比较长度memcmp 函数是通过返回值告知大小关系的。
相关知识回顾:
#C语言——学习攻略:探索字符函数和字符串函数(一)--字符分类函数,字符转换函数,strlen,strcpy,strcat函数的使用和模拟实现
#C语言——学习攻略:探索字符函数和字符串函数(二)--strcmp、strstr的使用和模拟实现以及strncpy、strncat、strncmp、strock、strerror函数的使用
结语:本篇文章到此结束,呈现了内存函数的内容,内涵丰富,大家要多次回顾,如果这篇文章对你的学习有帮助的话,欢迎一起讨论学习,你这么帅、这么美给个三连吧~~~