内存函数:memcpy(拷贝),memmove(拷贝),memcmp(比较),memset(设置)
内存函数
- 一.memcpy(内存拷贝1)
- 1.函数使用
- 2.模拟实现
- 二.memmove(内存拷贝2)
- 1.函数使用
- 2.模拟实现
- 三.memcmp(内存比较)
- 1.函数使用
- 2.模拟实现
- 四.memset(内存设置)
- 1.函数使用
- 2.模拟实现
前言:
- 之前我们学习了一些字符串库函数,并且模拟实现了它们。但是它们只能作用于字符串,那有没有适用于各种数据类型的函数呢?答案是有的,现在我将为你介绍——内存函数(memory function)
- 内存函数头文件——string.h
一.memcpy(内存拷贝1)
1.函数使用
void* memcmp(void* destination, const void* source, size_t num);
- memcpy函数用于拷贝两块独立空间中的数据(不可重叠),将源内存块按照每一个字节拷贝到目标内存块,num表示要拷贝字节的数目。destination 与 source 都是拷贝与被拷贝的起始地址。
#include #include int main() { int arr1[] = { 1,2,3,4,5,6,7 }; int arr2[10] = { 0 }; int arr3[] = { 1,2,3,4,5,6,7,8,9,10 }; memcpy(arr2, arr1, 24); memcpy(arr3 + 2, arr3, 20); return 0; }
- 观察到arr1将前6个整形拷贝到了arr2中,也就是24个字节,是没有问题的。
- 而第二个操作本来打算:将 arr3 中的 1,2,3,4,5 拷贝到 arr3 中的 3,4,5,6,7 上,但是得到的是1,2,1,2,1这是因为将1,2拷贝到3,4上,原来的内容就被修改了,达不到要求的效果。
总结:
- 函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。
- 这个函数在遇到 ‘
- 用于拷贝两块独立空间中的数据,如果source和destination有任何的重叠,复制的结果都是未定义的。 ’ 的时候并不会停下来。
- 由于不知道拷贝什么样的数据,所以参数的指针类型为void*(可接收任意类型指针),在函数内部强制类型转换为 char*,可以用于每个字节拷贝。
2.模拟实现
void* my_memcpy(void* destination, const void* source, size_t num) { assert(destination && source);//断言,当二者之一指针为NULL则报错 void* ret = destination;//存起始地址便于返回 while (num--)//循环拷贝,每次拷贝一个字节 { *(char*)destination = *(char*)source; destination = (char*)destination + 1;//强制类型转换的临时的(char*)destination++;(错误) source = (char*)source + 1; } return ret; }
- 首先是必不可少的断言操作,其次就是要保留目标空间的起始地址便于之后的返回。然后拷贝每一个字节中的内容,所以要循环 num 次。每拷贝一个字节,两个指针向后移动,直到循环结束为止。拷贝结束后返回起始地址即可。
二.memmove(内存拷贝2)
注意:在对 destination 和 source 指针进行操作时,要先将它们强制类型转换为 char* 类型的指针。(char* 类型的指针解引用操作时向后访问一个字节的内容)。而 void* (泛型指针)是不能进行解引用操作的。
1.函数使用
void* memmove(void* destination, const void* source, size_t num);
- 上面学习了memcpy函数,得知其不能用于处理重叠的内存之间的数据拷贝,那么这样实现重叠部分的数据拷贝呢?memmove会带你实现。
#include #include int main() { int arr1[] = { 1,2,3,4,5,6,7,8,9,10 }; memmove(arr1 + 2, arr1, 20); return 0; }
- memmove函数用于拷贝两块空间中的数据(可以重叠),将源内存块按照每一个字节拷贝到目标内存块,num表示要拷贝字节的数目。destination 与 source 都是拷贝与被拷贝的起始地址。
- memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
- 如果源空间和目标空间出现重叠,就得使用memmove函数处理。
- 在同一块内存中:重叠时,当dest指针 > src指针,采用从前向后拷贝。
- 在同一块内存中:重叠时,当dest指针
- 在同一块内存中:若没有重叠,二者都可以采用。
- 在不同块内存中:二者都可以采用。
总结:
2.模拟实现
分析:
1.当要将紫色区间拷贝到蓝色区间,若采用从前往后(1,2,3,4,5)拷贝,会改变紫色区间中要进行拷贝的数据。换个思路:采用从后往前拷贝,能避免这个问题。
2.当要将紫色区间拷贝到蓝色区间,若采用从后往前(7,6,5,4,3)拷贝,会改变紫色区间中要进行拷贝的数据。换个思路:采用从前往后拷贝,能避免这个问题。
总结:
三.memcmp(内存比较)
void* my_memmove(void* destination, const void* source, size_t num) { assert(destination && source);//断言 void* ret = destination;//保存起始地址 if (destination
1.函数使用
int memcmp(const void* ptr1, const void* ptr2, size_t num);
#include #include int main() { int arr1[] = { 1,257 };//01 00 00 00 01 01 00 00 int arr2[] = { 1,2 }; //01 00 00 00 02 00 00 00 int ret = memcmp(arr1, arr2, 8); printf("%d\n", ret); return 0; }
- memcmp函数用于比较两个内存块大小的函数。它会比较从 ptr1 和 ptr2 指针开始的第一个字节。当 *ptr1 大于 *ptr2 的时候返回一个大于0的数;当 *ptr1 等于 *ptr2 的时候返回0;当 *ptr1 小于 *ptr2 的时候返回一个小于0的数。比较完一次,ptr1 与 ptr2 指向下一个字节,循环 num 次,直到结束为止 。
- 在VS中内存采用的是小端存储方式。
- 数字在内存中是以2进制补码的形式存储的,但是为了更好的观察,以16进制展现出来。
- arr1与arr2中的前4个字节的内容都相同;但第5个字节,1 assert(str1 && str2); while (*(char*)str1 == *(char*)str2 && num--)//1.*(char*)str1 != *(char*)str2 2.num==0 { str1 = (char*)str1 + 1; str2 = (char*)str2 + 1; } if(num==0)//二者相同 return 0; else//二者不同 return *(char*)str1 - *(char*)str2; } char arr[] = "hello world"; memset(arr + 6, 'x', 5); printf("%s\n", arr); return 0; } int arr[10] = { 0 }; memset(arr, 1, 40); int i = 0; for (i = 0; i
- 上面学习了memcpy函数,得知其不能用于处理重叠的内存之间的数据拷贝,那么这样实现重叠部分的数据拷贝呢?memmove会带你实现。
- memcpy函数用于拷贝两块独立空间中的数据(不可重叠),将源内存块按照每一个字节拷贝到目标内存块,num表示要拷贝字节的数目。destination 与 source 都是拷贝与被拷贝的起始地址。
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理!
部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!
图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!