C语言之详解内存操作函数
创始人
2024-01-25 07:44:39
0

个人主页:平行线也会相交
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创
收录于专栏【C/C++】
在这里插入图片描述

目录

  • 前言
  • memcpy
    • 模拟实现
  • memmove
    • 模拟实现
  • memcmp
  • memset

前言

memcpy叫做内存拷贝,memmove叫做内存移动,memcmp叫做内存比较,大家可以想一想为什么要有这些函数呢?我们不是已经由字符串拷贝、字符串比较、字符串追加这些函数了吗?

我们首先知道,所谓的字符串函数:strcpy、strcat、strcmp、strncpy、strncat、strncmp这些函数操作的对象是字符串,或多或少都会跟'\0'打交道。
假设我们现在要操作的是一个数组,比如我们要拷贝整型数组、浮点型数组、又或者是结构体数组,那我们还能不能用strcpy函数来进行拷贝呢?不妨来试一下,请看:
在这里插入图片描述
可以清楚的看到这里会弹出警告⚠。报警告只是一方面,那它能不能把数组arr1中的内存拷贝到数组arr2中去呢?请看调试结果:
在这里插入图片描述
可以看到并没有把数组arr1的内容拷贝到数组arr2中去,**但是数组arr2中的首元素为什么会变成1呢?**我们先来看数组arr1中的1 2 3 4 5在内存中的布局:

当前机器是小端存储
01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00

在这里插入图片描述
由此我们可以发现这里用strcpy函数压根就做不到,stycpy的局限性就体现出来了。
由此也出现了内存函数:memcpy、memmove、memcmp、memset

memcpy

memcpy叫做内存拷贝,只要是放到内存中的数据我们都可以进行拷贝。

1.函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
2.这个函数在遇到'\0'的时候并不会停下来。
3.如果source和destination有任何的重叠,复制的结果都是未定义的。

在这之前我们还是要回顾以前的回调函数qsort中的void*-通用类型的指针-无类型指针-即可以接受任意类型的指针
所以,我们来看memcpy函数
的参数:void* memcpy(void * destination, const void * source ,size_t num);这种参数设计的方式与函数strncpy的参数设计方式类似,可以对照学习一下。注意这里参数num的单位是字节。
我们来看举例:
在这里插入图片描述
再来举一个结构体类型的数组,请看举例:
在这里插入图片描述

知道这里我们就大体对函数memcpy的功能有了一定了解,下面我们来模拟实现memcpy函数的功能。

模拟实现

#include
#include
#include
struct S
{char name[20];int age;
};
void* my_memcpy(void* dest, const void* src, size_t num)
{void* ret = dest;assert(dest && src);while (num--){*(char*)dest = *(char*)src;++(char*)dest;++(char*)src;}return ret;
}
int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[5] = { 0 };struct S arr3[] = { {"张三",20},{"李四",30} };struct S arr4[3] = { 0 };my_memcpy(arr2, arr1, sizeof(arr1));my_memcpy(arr4, arr3, sizeof(arr3));return 0;
}

然而我们写的这个模拟memcpy函数只能处理内存不重叠的情况;当内存出现重叠时,我们会有专门的函数memmove来处理。

memmove

在这里插入图片描述
所以,memmove函数可以处理这种重叠拷贝的现象。
刚刚说过我们写的my_memcpy函数无法处理重叠拷贝的情况,其实库里的memcpy函数是可以实现重叠拷贝的情况的,请看举例:
在这里插入图片描述
可以看到库里的memcpy函数的确可以处理重叠拷贝的情况,但是我们刚刚写的my_memcpy函数却无法做到,这并不意味的我们✍的这个my_memcpy函数不好。
因为C语言标准规定:memcpy函数只需要能处理不重叠的内存拷贝就可以了。
memmove函数用来处理内存重叠的拷贝。

所以说,我们写的my_memcpy函数刚刚好满足C语言的标准。并没有一些额外的功能。
下面我们来模拟实现memmove函数。

模拟实现

这里涉及到到底是从前向后拷贝还是从后向前拷贝的问题。
在这里插入图片描述
在这里插入图片描述

#include
#include
void* my_memmove(void* dest, const void* src, size_t count)
{void* ret = dest;assert(dest && src);if (dest < src){//前->后while (count--){*(char*)dest = *(char*)src;++(char*)dest;++(char*)src;}}else{//后->前while (count--){*((char*)dest + count) = *((char*)src + count);}}return ret;}
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };my_memmove(arr + 2, arr, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}

在这里插入图片描述
这种写法也可以:

#include
#include
void* my_memmove(void* dest, const void* src, size_t count)
{void* ret = dest;assert(dest && src);if (dest < src||(char*)dest>(char*)src+count){//前->后while (count--){*(char*)dest = *(char*)src;++(char*)dest;++(char*)src;}}else{//后->前while (count--){*((char*)dest + count) = *((char*)src + count);}}return ret;}
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };my_memmove(arr + 2, arr, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}

memcmp

memcmp:int memcmp(const void * ptr1, const void * ptr2, size_t num );(内存比较)

比较从ptr1和ptr2指针开始的num个字节

请看举例:

在这里插入图片描述
说明前8个字节一样。倘若我们要比较前9个字节呢?请看:
在这里插入图片描述
注意是小端存储。

memset

memset—内存设置
memset:void *memset(void *dest,int c,size_t count);
这里的c是你要设置的字符是什么。
这里的count是你要设置多少个字符。

请看举例:
在这里插入图片描述
那我们可不可以这样使用呢?请看:

#include
#include
int main()
{int arr[10] = {0};memset(arr, 1, 10);return 0;
}

上述的代码就是打错特错,千万要记住:memset(arr,1,10),这里的10并不是10个元素的意思,而是10个字节。
如果你非要看一下调试结果,可以🙆‍,请看:
在这里插入图片描述
这是怎么一回事呢?数组arr的大小是40个字节,而这里在40个字节中我们对前10个字节进行更改,而且前十个字节我们改成了1。
即:01 01 01 01 01 01 01 01 01 01 00 00 00 00...
在这里插入图片描述
切记:memset函数可以把一块任何什么数据的空间都可以改,但是它改的单位是字节,我们要改几个字节,每个字节的内容又是什么。

相关内容

热门资讯

海景房直播暴露我军舰动态,国家...   5日,“国家安全部”微信公众号公布一则用军港当背景直播暴露我军舰动态的案例:
身无分文黑户怎样快速翻身(30... 一个人三十岁,欠了几万的债。他的人生毁了吗?有这种想法的人,你已经被废了。我以为我欠了几百万,几千万...
2021年加盟好项目,2021... 专注创业,让你不再孤独的小鸽子又来了。上一次小鸽子在后台默默回答是小哥哥还是小姐姐的问题后,有热心创...
“根本做不完!”外卖大战白热化... “太疯狂了,周六晚上,全国人民都在熬夜点外卖。喝不完,根本喝不完。”不少网友感叹。与之相呼应的是奶茶...
“黄山好人”汪笃银:退役不褪色...   汪笃银,男,1952年12月出生,中共党员,徽州区岩寺镇人。他既是硝烟战场上的铁血硬汉,也是社区...
syb以往相关经验(拥有多次创... SYB培训是高校经常开展的一种培训,是大学生创业课程的重要组成部分。SYB在英语中是“创业”的缩写,...
义乌小商品代加工外发,温州小商... (图片/温州日记)温州火车站的金瑞小商品综合体前几年常和朋友来这里买帽子、发卡等小东西。之后有了淘宝...
项目代理服务有哪些地方(找项目... 陶吧,一个乡镇代理项目玩泥巴是孩子的天性,但在城市里,这些乐趣几乎被剥夺了。陶瓷艺术吧开业后,孩子们...
红色基因铸魂、绿色产业赋能——...   央视网消息:1940年2月23日,民族英雄杨靖宇将军在濛江雪原与日本侵略者英勇战斗至生命最后一刻...
焦点访谈丨跨区域招聘、开设微专...   2025年全国高校毕业生预计达1222万人。当年年刷新的毕业生数字和经济转型期的岗位结构性矛盾发...