【内存操作】C语言内存函数介绍以及部分模拟实现【初学者保姆级福利】超详细的解释和注释
C语言 内存函数的使用以及部分模拟实现
求个赞求个赞求个赞求个赞 谢谢
先赞后看好习惯 打字不容易,这都是很用心做的,希望得到支持你 大家的点赞和支持对于我来说是一种非常重要的动力 看完之后别忘记关注我哦!️️️
看完这篇博客,除了学会这个几个内存函数之外,相信你会对计算机的内存,以及指针的理解和应用会提高一个层次
强烈建议本篇收藏后食用
memcpy函数
原型:void* memcpy(void* destination, const void* source, size_t num);
函数介绍
图片取自:www.cplusplus.com

该函数可以将内存中固定字节数拷贝到另一块内存空间中
例子:
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[20] = { 0 };
memcpy(arr2,arr1,20);
//将arr1所指向的内存中取20个字节的内容拷贝到arr2中
return 0;
}
我们f10并打开监视就可以看到arr2已经被拷贝了20个字节的结果:1,2,3,4,5.
memcpy的模拟实现
void* my_memcpy(void* dest, const void* src, size_t num)
{
void* ret = dest;
//为了防止dest在后续操作中丢失地址
//我们用一个ret来记录dest一开始的地址
//拷贝完成后我们直接返回ret即可
assert(dest && src);//断言dest和src都不是空指针
int i = 0;
for (i = 0; i < num; i++)
{
*((char*)dest) = *((char*)src);//因为void*类型指针
//不能够解引用,因此强制转化成char*类型,每次拷贝一个字节即可。
dest = (char*)dest + 1;
src = (char*)src + 1;
//每次拷贝完一个字节,拷贝下一个字节,一共拷贝num次
}
return ret;//返回拷贝完的地址
}
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[20] = { 0 };
int i = 0;
my_memcpy(arr2, arr1, 24);
for (i = 0; i < 6; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}

这样我们就成功拷贝了
注意:这种模拟实现方式是不可以处理重叠的内存的,因为我们一个一个字节拷贝,如果前面的拷贝改变了后面即将要拷贝的内存,就会使得我们得不到想要的答案。
而此时,我们就需要memmove函数,这个函数是可以处理重叠的内存的
memmove函数
图片取自:www.cplusplus.com

int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(arr1 + 2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
memmove是可以处理重叠的内存的
模拟实现memmove
为了可以处理重叠的内存,我们要分两种情况。
第一种:从前向后拷贝
第二种:从后向前拷贝。
如果我们的src在dest后面我们就必须从后向前拷贝
如果我们的dest在src后面,我们就必须从前向后拷贝。
这样才能使得我们在拷贝内存的时候不会有因为重叠而造成错误的结果。
对于这一部分不明白的伙伴可以给我私信留言。
void*my_memmove(void* dest, const void* src, size_t num)
{
void* ret = dest;
assert(dest && src);
if (dest < src)//判断拷贝方向
{
//从前向后
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else
{
//从后向前
while (num--)
{
*((char*)dest + num) = *((char*)src + num);
//因为这里的num--所以,我们这样写就可以了,每次--交换一次
//直到循环跳出
}
}
return ret;
}
//memcpy-只是先了不重叠的拷贝,而vs中的实现既可以拷贝不重叠,也可以拷贝重叠内存
//vs库里面的memcpy是可以拷贝重叠的,过程和我们写的memmove一样
//但是不保证每一种编译器都可以,所以,我们操作重叠内存的时候,就用memmove就可以了
对于这一部分不明白的伙伴可以给我私信留言。
memcmp函数
图片取自:www.cplusplus.com

内存比较函数
这个函数与strcmp函数十分相似
原型:int memcmp ( const void * ptr1, const void * ptr2, size_t num );
使用过程:
int main()
{
float arr1[] = { 1.0,2.0,3.0,4.0 };
float arr2[] = { 1.0,3.0 };
int ret = memcmp(arr1, arr2, 4);
printf("%d\n", ret);
//返回值和strcmp很相似
return 0;
}
这个函数比较简单,在这里就不给大家模拟实现了,相信你看了上面两个函数的模拟实现过程,模拟实现这个函数不成问题。
memset函数
图片取自:www.cplusplus.com

memset内存设置函数
原型:void * memset ( void * ptr, int value, size_t num );
可以将ptr指向的num个字节的内存设置成想要的值。
使用过程
int main()
{
int arr[10] = { 0 };//前20个字节设置成1
memset(arr,1,20);//以字节为单位设置,每个字节都是1
//01 01 01 01肯定不是1
//如果想把每个元素设计成1,不能用memset
//字符可以
char arr2[10] = { 0 };
memset(arr2, 'a', 5);
printf("%s ", arr2);
return 0;
}
注意,这里得到的结果肯定不会是1的,我们是把20个字节设置成1,不是20个整型设置成1
以上就是这四个函数的全部内容了,非常感谢你能看到这里,别忘了点关注,点收藏,点大拇指,一键三连再走哦!
【内存操作】C语言内存函数介绍以及部分模拟实现【初学者保姆级福利】超详细的解释和注释的更多相关文章
- [原创] Delphi Win API函数 操作帮助文件 HtmlHelpA函数介绍
Delphi Win API函数 操作帮助文件 HtmlHelpA函数介绍 函数原型:HWND HtmlHelpA( HWND hwndCaller, LPCSTR pszFile, UINT uCo ...
- c# 外挂操作(内存操作)(内存读写取窗口句柄移动窗口取模块地址)工具类
来源于网上 参考 https://www.cnblogs.com/fuhua/p/5877781.html 等众多文章 详情取看我第二个例子封装功能较多 https://www.cnblogs.co ...
- C语言学习笔记--内存操作常见错误
1. 野指针 (1)指针变量中的值是非法的内存地址,进而形成野指针 (2)野指针不是 NULL 指针,是指向不可用内存地址的指针 (3)NULL 指针并无危害,很好判断,也很好调试 (4)C 语言中无 ...
- 【Go语言入门系列】Go语言工作目录介绍及命令工具的使用
[Go语言入门系列]前面的文章: [保姆级教程]手把手教你进行Go语言环境安装及相关VSCode配置 [Go语言入门系列](八)Go语言是不是面向对象语言? [Go语言入门系列](九)写这些就是为了搞 ...
- 【保姆级教程】手把手教你进行Go语言环境安装及相关VSCode配置
[Go语言入门系列]前面的文章: [Go语言入门系列](七)如何使用Go的方法? [Go语言入门系列](八)Go语言是不是面向对象语言? [Go语言入门系列](九)写这些就是为了搞懂怎么用接口 本篇文 ...
- C语言 mmap()函数(建立内存映射) 与 munmap()函数(解除内存映射)
mmap将一个文件或者其它对象映射进内存.文件被映射到多个页上,如果文件的大小不是所有页的大小之和, 最后一个页不被使用的空间将会清零.mmap在用户空间映射调用系统中作用很大. 条件 mmap()必 ...
- C语言嵌入式系统编程修炼之三:内存操作
数据指针 在嵌入式系统的编程中,常常要求在特定的内存单元读写内容,汇编有对应的MOV指令,而除C/C++以外的其它编程语言基本没有直接访问绝对地址的能力.在嵌入式系统的实际调试中,多借助C语言指针所具 ...
- 【C/C++】C语言嵌入式编程修炼·背景篇·软件架构篇·内存操作篇
C 语言嵌入式系统编程修炼之一:背景篇 不同于一般形式的软件编程,嵌入式系统编程建立在特定的硬件平台上,势必要求其编程语言具备较强的硬件直接操作能力.无疑,汇编语言具备这样的特质.但是,归因于汇编语言 ...
- 【嵌入式开发】裸机引导操作系统和ARM 内存操作 ( DRAM SRAM 类型 简介 | Logical Bank | 内存地址空间介绍 | 内存芯片连接方式 | 内存初始化 | 汇编代码示例 )
[嵌入式开发]ARM 内存操作 ( DRAM SRAM 类型 简介 | Logical Bank | 内存地址空间介绍 | 内存芯片连接方式 | 内存初始化 | 汇编代码示例 ) 一. 内存 ...
- C语言-内存函数的实现(一)之memcpy
C语言中的内存函数有如下这些 memcpy memmove memcmp memset 下面看看memcpy函数 memcpy 我们想想,之前有那个字符串拷贝的函数,即strcpy函数.都有拷贝的函数 ...
随机推荐
- Codeforce:1300B. Assigning to Classes (math)
解题思路 题目说的意思是,给一个2n个数的数组,注意n为奇数,将这个数组平均分为2份,假设为c1和c2. c1和c2是奇数个元素的数组,比如数组[1,2,3],那么中位数就是2. 那么如何求得中位数差 ...
- 【数据库】E-R图向关系模型转换的规则
E-R图向关系模型转换的规则: (1) 一个实体型转换为一个关系模式,实体的属性就是关系的属性,实体的码(关键字)就是关系的码. (2) 一个 1:1 联系可以转换为一个独立的关系模式,也可以与任意一 ...
- 2018年第九届 蓝桥杯C组 C/C++决赛题解
蓝桥杯历年国赛真题汇总:Here 1.年龄问题 s夫人一向很神秘.这会儿有人问起她的年龄,她想了想说: "20年前,我丈夫的年龄刚好是我的2倍,而现在他的年龄刚好是我的1.5倍". ...
- CPLEX通过Python API获取Gap值的方法
写在前面 最近在使用Cplex求解模型,尽管Cplex的Python API会自动输出引擎日志,但在多次求解中一次次看引擎日志找Gap值并做实验记录很麻烦,所以需要找到获取Gap值的方法.然而我在Cp ...
- Linux 文件目录配置及命令总结
前言 在Linux中,一切皆文件,而每一个文件和目录都是从根目录开始的 Linux文件目录的作用 /bin目录:用来存放二进制可执行命令的目录,用户常用的命令都存在该目录下. /sbin目录:用来存放 ...
- idea新建spring boot 项目右键无package及java类的选项
新创建的spring boot项目,只有一个默认的资源目录及启动配置. 在 group 的目录下右键新建包路径时 ,发现没有package选项,也没有Java Class的选项: 解决办法: File ...
- 针对docker中的mongo容器增加鉴权
1. 背景 业务方的服务器经安全检查,发现以docker容器启动的mongo未增加鉴权的漏洞,随优化之 2. 配置 mongo以docker compose方式启动,镜像的版本号为4.2.6,dock ...
- Memory Bist
SRAMC主要是对SRAM进行控制 对于SRAM的逻辑,根据地址将数据存储到SRAM中,然后根据地址将SRAM中的数据读取出来 如何测试Memory,生产工艺原因造成的问题,采用DFT或者Bist测试 ...
- [java] - servlet路径跳转
Index.jsp <a href="servlet/HelloServlet">servlet/HelloServlet</a><br> &l ...
- 【 js 】 构造函数返回的注意事项
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...