目录:内存操作函数
一:memcpy函数(内存拷贝)
二:memmove函数(内存拷贝)
三:memset函数(内存设置)
四:memcmp函数(内存比较)
一:memcpy函数
memcpy内存函数的实现原理:
将 num 个字节的数据从 source 指向的位置开始拷贝到 destination 指向的内存块中,这个函数在遇到0’的时候并不会停下。
所以memcpy函数中需要传入三个参数,分别是目标内存空间的首地址,被拷贝内存空间的首地址和拷贝字节数。
memcpy函数可以拷贝字符串数据,整形数组数据,结构体数据等诸多类型......,但因为memcpy内存函数不能够自身拷贝,memcpy函数不能够拷贝内存重叠区的数据,因此存在着一定的局限性,在这里,小夏推荐大家在遇到数据拷贝时应用接下来的memmove函数可以完美的避免所有的不稳定因素。
二:memmove函数
memmove内存函数的实现原理(内存存在重叠,无重叠都可使用):
用于拷贝内存数据,如果目标区域和源区域有重叠的话,
memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,
但复制后源内容会被更改。但是当目标区域与源区域没有重叠则和memcpy函数功能相同
memmove函数实现重叠内存过程:
总结来说,在遇到内存重叠的情况下分为三中情况:
1.从前向后拷贝(内存空间存在重叠)->如果source的地址高于disnation的地址:则进行常规的赋值,及从source的地址依次向后对disnation地址进行拷贝,直到拷贝的字节数达到size_t num,及拷贝完成。
2.从后向前拷贝(内存空间存在重叠)->如果source的地址低于disnation的地址:则进行逆序的赋值,及从source+num的地址向前对disnation+num地址进行拷贝,直到拷贝的字节数达到size_t num,及拷贝完成。
3.从前向后拷贝或-从后向前拷贝都可(内存空间不存在重叠)。
模拟实现memmove函数:
我们可以自己写一个my_memmove函数来模拟实现memmove函数的功能
首先定义函数void* my_memmove(void* s1, const void* s2, size_t len)
因为memmove是拷贝内存的函数,对于内存中被拷贝的是什么数据类型,并没有限制,所以传入的参数数据类型用void*,返回值也是无类型的地址。
size_len是一个无符号整数类型,表示想要拷贝的字节数,所以在my_memmove函数内部,我们可以这样写
#include<stdio.h> #include<assert.h> void* my_memmove(void* s1, const void* s2, size_t len) { assert(s1); assert(s2); void* ret = s1; int i = 0; if (((char*)s2)>((char*)s1))//从s2的前端依次拷贝 { for(i=0;i<len;i++) { *((char*)s1) = *((char*)s2); (char*)s1 = (char*)s1 + 1; (char*)s2 = (char*)s2 + 1; } } else { while (len--)//从s2的后端开始拷贝 { *((char*)s1 + len) = *((char*)s2 + len); } } return ret; } int main() { int arr[20] = { 0 }; int i = 0; for (i = 0; i < 10; i++) { arr[i] = i + 1; } my_memmove(arr + 1, arr , sizeof(int) * 5); for (i = 0; arr[i] != 0; i++) { printf("%d ", arr[i]); } return 0; }
三:memset函数
memset内存函数的实现原理:num字节对内存块进行初始化
将value的值依次从ptr地址,依次向后size_t num个字节的内存空间进行赋值。
memset的函数定义:
模拟实现memset函数:
我们可以自己写一个my_memset函数来模拟实现memset函数的功能
首先定义函数void* my_memset(void * ptr, int value, size_t num)
因为memset是拷贝内存的函数,对于内存中被拷贝的是什么数据类型,并没有限制,所以传入的参数数据类型用void*,返回值也是无类型的地址。
size_num是一个无符号整数类型,表示想要赋值的字节数,所以在my_memset函数内部,我们可以这样写
#include<stdio.h> void* my_memset(void* ptr, int value, size_t num) { while (num--) { *((char*)ptr) = value + '0'; ptr = (char*)ptr + 1; } } int main() { char arr[] = "abcdefghijk"; my_memset(arr+1, 6, 3); printf("进过赋值后的结果->%s\n", arr); return 0; }
在模拟实现memset函数中有一个小小的知识点就是:将数字转化成字符该如何转化,字符‘0’的ASCLL值为48,数字0的ASCLL值为0,所以将数字加上字符‘0’就可得到相应的字符。
该函数实现的结果为:
四:memcmp函数
memcmp内存函数的实现原理:用于比较比较内存的前N个字节
字符串大小的比较是以ASCII 码表上的顺序来决定,次顺序亦为字符的值。memcmp()首先将s1 第一个字符值减去s2 第一个字符的值,若差为0 则再继续比较下个字符,若差值不为0 则将差值返回。
两个字符串内容完全一样,返回0;
若S1大于S2,则大于0,
反之则小于0;
memcmp的函数定义:从ptr1内存空间和ptr2内存空间依次向后进行比较size_t num个字节大小,且per1和ptr2进const修饰不可改变其内容。
模拟实现memcmp函数:
我们可以自己写一个my_mecmp函数来模拟实现memcmp函数的功能
首先定义函数void* my_memcmp(const void*ptr1,const void*ptr2,size_t num)
#include<stdio.h> void* my_memcmp(const void* ptr1, const void* ptr2, size_t num) { while (num--) { if (*(char*)ptr1 == *(char*)ptr2) { ptr1 = (char*)ptr1 + 1; ptr2 = (char*)ptr2 + 1; } else { return *(char*)ptr1 - *(char*)ptr2; } } } int main() { char s1[] = "abcd456ef"; char s2[] = "abef789nmn"; int ret=my_memcmp(s1, s2, 5); printf("差值为->%d", ret); return 0; }
其执行结果为:
执行结果:
my_memcmp(s1+7, s2,5):1 //字符串s1>字符串s2, 返回正值
my_memcmp(s1, s2,5):-1 // 字符串s1<字符串s2,返回负值
my_memcmp(s1, s2,2):0 //字符串s1=字符串s2, 返回0
如果觉得文章不错,期待你的一键三连哦,你个鼓励是我创作的动力之源,让我们一起加油,顶峰相见!!!