目录
一、memcpy、memmove使用和模拟实现
(一)memcpy的使用和模拟实现
1、代码演示:
(1)memcpy拷贝整型
(2)memcpy拷贝浮点型
2、模拟实现
(二)memmove的使用和模拟实现
1、代码实现
(1)内存没有重叠
(2)内存重叠
2、模拟实现
二、memset、memcmp函数的使用
(一)memset函数的使用
1、代码实现
(1)针对字符数组
(2)针对整型数组
2、总结
(二)memcmp函数的使用
1、代码实现:
(1)比较前16个字节
(2)比较17个呢
2、总结
结尾
🔥个人主页:艾莉丝努力练剑
🍓专栏传送门:《C语言》
🍉学习方向:C/C++方向
⭐️人生格言:为天地立心,为生民立命,为往圣继绝学,为万世开太平
前言:前面几篇文章介绍了c语言的一些知识,包括循环、数组、函数、VS实用调试技巧、函数递归、操作符、指针、字符函数和字符串函数、结构体、联合和枚举、动态内存管理、文件操作、编译和链接、预处理等,在这篇文章中,我将开始介绍C语言内存函数的一些重要知识点!对C语言内存函数感兴趣的友友们可以在评论区一起交流学习!
一、memcpy、memmove使用和模拟实现
(一)memcpy的使用和模拟实现
memcmp:memory copy——内存拷贝;
代码原型:
void* memcpy(void* destination, const void* source, size_t num);
三板斧——
功能:(1)memcpy 是完成内存块拷贝的,不关注内存中存放的数据是什么;(2)函数 memcpy 从 source 的位置开始向后复制 num 个字节的数据到 destination 指向的内存位置;(3)如果 source 和 destination 有任何的重叠,复制的结果都是未定义的 (内存重叠的情况使用memmove 就行)。注: memcpy 的使用需要包含 <string.h>。参数:destination :指针,指向目标空间,拷贝的数据存放在这里;source :指针,指向源空间,要拷贝的数据从这里来;num :要拷贝的数据占据的字节数。返回值:拷贝完成后,返回目标空间的起始地址。
1、代码演示:
(1)memcpy拷贝整型
strcpy、strncpy拷贝字符串的,是有局限性的;
拷贝一个整型数组呢?结构体数组呢?
#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };// 0 1 2 3 4 5...int arr2[20] = { 0 };// 0 1 2 3 4 5...//想把arr1中的10个整数,拷贝到arr2中//循环遍历//memcpymemcpy(arr2, arr1, 40);return 0;
}
(2)memcpy拷贝浮点型
#include<stdio.h>int main()
{int arr1[] = { 1.2f,2.2f,3.2f,4.5f,5.5f };int arr2[20] = { 0 };memcpy(arr2, arr1, 5 * sizeof(float));return 0;
}
2、模拟实现
#include<stdio.h>void* my_memcpy(void* dest, const void* src, size_t num)
{void* ret = dest;assert(dest && src);while (num--){*(char*)dest = *(char*)src;src = (char*)src + 1;dest = (char*)dest + 1;}return ret;
}
//4*3 + 3int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[20] = { 0 };my_memcpy(arr2, arr1, 40);return 0;
}
那么我们可不可以把1,2,3,4,5这五个整型拷贝到3,4,5,6,7这五个整型的位置(覆盖了):
下面是我们自己写的代码演示:
#include<stdio.h>
#include<assert.h>void* my_memcpy(void* dest, const void* src, size_t num)
{void* ret = dest;assert(dest && src);while (num--){*(char*)dest = *(char*)src;src = (char*)src + 1;dest = (char*)dest + 1;}return ret;
}
//4*3 + 3int main()
{//int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };//int arr2[20] = { 0 };//my_memcpy(arr2, arr1, 40);int arr[] = { 1,2,3,4,5,6,7,8,9,10 };my_memcpy(arr + 2, arr, 20);return 0;
}
我们发现达不到我们想要的效果。
那索性就不要用my_memcpy了,下面是我们直接调用库里的函数实现的:
#include<stdio.h>
#include<assert.h>void* my_memcpy(void* dest, const void* src, size_t num)
{void* ret = dest;assert(dest && src);while (num--){*(char*)dest = *(char*)src;src = (char*)src + 1;dest = (char*)dest + 1;}return ret;
}
//4*3 + 3int main()
{//int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };//int arr2[20] = { 0 };//my_memcpy(arr2, arr1, 40);int arr[] = { 1,2,3,4,5,6,7,8,9,10 };memcpy(arr + 2, arr, 20);return 0;
}
监视打开:
memcpy:不重叠的就可以了,memcpy连重叠的都能搞定。
(二)memmove的使用和模拟实现
memmove:可以处理不重叠的,也可以处理重叠内存。
代码原型:
void* memmove(void* destination, const void* source, size_t num);
三板斧——
功能:(1)memmove函数也是完成内存块拷贝的;(2)和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。注: memmove的使用也需要包含<string.h>。参数:destination :指针,指向目标空间,拷贝的数据存放在这里;source :指针,指向源空间,要拷贝的数据从这里来;num :要拷贝的数据占据的字节数。返回值:拷贝完成后,返回目标空间的起始地址。
1、代码实现
(1)内存没有重叠
#include<stdio.h>
#include<assert.h>int main()
{//内存没有重叠int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[20] = { 0 };//memcpy();memmove(arr2, arr1, 20);
}
(2)内存重叠
#include<stdio.h>
#include<assert.h>int main()
{//内存重叠int arr[] = { 1,2,3,4,5,6,7,8,9,10 };memmove(arr + 2, arr, 20);return 0;
}
2、模拟实现
#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>
#include<assert.h>
void * my_memmove(void* dest,void* src,size_t num)
{assert(dest && src);void* net = dest;if (dest < src){//前->后while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}else//2 3{while (num--){*((char*)dest + num) = *((char*)src + num);}}return net;
}
int main()
{//内存重叠int arr[] = { 1,2,3,4,5,6,7,8,9,10 };my_memmove(arr + 2, arr, 20);return 0;
}
二、memset、memcmp函数的使用
(一)memset函数的使用
代码原型:
void* memset(void* ptr, int value, size_t num);
三板斧——
功能:memset 函数是用来设置内存块的内容的,将内存中指定长度的空间设置为特定的内容。注: memset 的使用也需要包含 <string.h>。参数:ptr :指针,指向要设置的内存空间,也就是存放了要设置的内存空间的起始地址;value :要设置的值,函数将会把 value 值转换成 unsigned char 的数据进行设置的,也就是以字节为单位来设置内存块的;num :要设置的内存长度,单位是字节。返回值:返回的是要设置的内存空间的起始地址。
1、代码实现
(1)针对字符数组
//针对字符数组
#include<stdio.h>
#include<string.h>int main()
{char arr[] = "hello world";memset(arr + 2, 'x', 5);printf("%s\n", arr);return 0;
}
(2)针对整型数组
#include<stdio.h>
#include<string.h>int main()
{int arr[10] = { 0 };//能否将arr的每个元素设置为1memset(arr, 1, 40);return 0;
}
2、总结
当有一块内存空间需要设置内容的时候,就可以使用memset函数,值得注意的是memset函数对内存单元的设置是以字节为单位的。
(二)memcmp函数的使用
代码原型:
int memcmp(const void* ptr1, const void* ptr2, size_t num);
三板斧——
功能:
比较指定的两块内存块的内容,比较从ptr1和ptr2指针指向的位置开始,向后的num个字节。
注:memcmp 的使用需要包含 <string.h>。
参数:
ptr1 :指针,指向一块待比较的内存块;
ptr2 :指针,指向另外⼀块待比较的内存块;
num :指定的比较长度,单位是字节。返回值:![]()
1、代码实现:
(1)比较前16个字节
#include<stdio.h>
#include<string.h>int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[] = { 1,2,3,4,8 };int r = memcmp(arr1, arr2, 16);if (r > 0)printf(">\n");else if (r < 0)printf("<\n");elseprintf("==\n");return 0;
}
打开内存,观察一下:
输出结果:
(2)比较17个呢
#include<stdio.h>
#include<string.h>int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[] = { 1,2,3,4,8 };int r = memcmp(arr1, arr2, 17);if (r > 0)printf(">\n");else if (r < 0)printf("<\n");elseprintf("==\n");return 0;
}
打开内存,观察一下:
输出结果:
2、总结
(1)如果要比较2块内存单元的数据的大小,可以使用 memcmp 函数,这个函数的特点就是可以指定比较长度;(2)memcmp 函数是通过返回值告知大小关系的。
结尾
往期回顾:
字符函数和字符串函数(二):strncpy、strncat、strncmp函数的使用、strstr的使用和模拟实现、strtok函数的使用、strerror函数的使用
字符函数和字符串函数(一):字符分类函数、字符转换函数、strlen的使用和模拟实现、strcpy的使用和模拟实现、strcat的使用和模拟实现、strcmp的使用和模拟实现
C语言指针深入详解(六):sizeof和strlen的对比,【题解】数组和指针笔试题解析、指针运算笔试题解析
结语:本篇文章就到此结束了,本文为友友们分享了C语言内存函数相关的一些重要知识点,如果友友们有补充的话欢迎在评论区留言,在这里感谢友友们的关注与支持!