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语言内存函数介绍以及部分模拟实现【初学者保姆级福利】超详细的解释和注释的更多相关文章

  1. [原创] Delphi Win API函数 操作帮助文件 HtmlHelpA函数介绍

    Delphi Win API函数 操作帮助文件 HtmlHelpA函数介绍 函数原型:HWND HtmlHelpA( HWND hwndCaller, LPCSTR pszFile, UINT uCo ...

  2. c# 外挂操作(内存操作)(内存读写取窗口句柄移动窗口取模块地址)工具类

    来源于网上  参考 https://www.cnblogs.com/fuhua/p/5877781.html 等众多文章 详情取看我第二个例子封装功能较多 https://www.cnblogs.co ...

  3. C语言学习笔记--内存操作常见错误

    1. 野指针 (1)指针变量中的值是非法的内存地址,进而形成野指针 (2)野指针不是 NULL 指针,是指向不可用内存地址的指针 (3)NULL 指针并无危害,很好判断,也很好调试 (4)C 语言中无 ...

  4. 【Go语言入门系列】Go语言工作目录介绍及命令工具的使用

    [Go语言入门系列]前面的文章: [保姆级教程]手把手教你进行Go语言环境安装及相关VSCode配置 [Go语言入门系列](八)Go语言是不是面向对象语言? [Go语言入门系列](九)写这些就是为了搞 ...

  5. 【保姆级教程】手把手教你进行Go语言环境安装及相关VSCode配置

    [Go语言入门系列]前面的文章: [Go语言入门系列](七)如何使用Go的方法? [Go语言入门系列](八)Go语言是不是面向对象语言? [Go语言入门系列](九)写这些就是为了搞懂怎么用接口 本篇文 ...

  6. C语言 mmap()函数(建立内存映射) 与 munmap()函数(解除内存映射)

    mmap将一个文件或者其它对象映射进内存.文件被映射到多个页上,如果文件的大小不是所有页的大小之和, 最后一个页不被使用的空间将会清零.mmap在用户空间映射调用系统中作用很大. 条件 mmap()必 ...

  7. C语言嵌入式系统编程修炼之三:内存操作

    数据指针 在嵌入式系统的编程中,常常要求在特定的内存单元读写内容,汇编有对应的MOV指令,而除C/C++以外的其它编程语言基本没有直接访问绝对地址的能力.在嵌入式系统的实际调试中,多借助C语言指针所具 ...

  8. 【C/C++】C语言嵌入式编程修炼·背景篇·软件架构篇·内存操作篇

    C 语言嵌入式系统编程修炼之一:背景篇 不同于一般形式的软件编程,嵌入式系统编程建立在特定的硬件平台上,势必要求其编程语言具备较强的硬件直接操作能力.无疑,汇编语言具备这样的特质.但是,归因于汇编语言 ...

  9. 【嵌入式开发】裸机引导操作系统和ARM 内存操作 ( DRAM SRAM 类型 简介 | Logical Bank | 内存地址空间介绍 | 内存芯片连接方式 | 内存初始化 | 汇编代码示例 )

    [嵌入式开发]ARM 内存操作 ( DRAM SRAM 类型 简介 | Logical Bank | 内存地址空间介绍 | 内存芯片连接方式 | 内存初始化 | 汇编代码示例 )     一. 内存 ...

  10. C语言-内存函数的实现(一)之memcpy

    C语言中的内存函数有如下这些 memcpy memmove memcmp memset 下面看看memcpy函数 memcpy 我们想想,之前有那个字符串拷贝的函数,即strcpy函数.都有拷贝的函数 ...

随机推荐

  1. AtCoder Beginner Contest 168 (A~E,E题很有意思)

    比赛链接:Here AB水题, C - : (Colon) 时针转过得角度为:\(2π \times \frac{h + \frac m{12}}{12}\) 分针转过得角度为:\(2π \times ...

  2. 0x61 图论-最短路

    B题 Telephone Lines https://ac.nowcoder.com/acm/contest/1055/B 中文题面:https://www.luogu.com.cn/problem/ ...

  3. 2020年了,再不会webpack敲得代码就不香了(近万字实战)

    https://zhuanlan.zhihu.com/p/99959392?utm_source=wechat_session&utm_medium=social&utm_oi=619 ...

  4. ASP.Net Core 5.0 MVC Session的添加,及它与Cookie的关系

    1.在控制器上新增一个方法 public IActionResult SessionAndCookie() { string result = HttpContext.Session.GetStrin ...

  5. 小白学正则表达式之 regexp

    1. 正则表达式介绍 正则表达式是程序文本处理常用的模板模式,按照解析正则表达式的引擎可将正则表达式分为 POSIX 基础正则表达式(Basic regular expression,BRE) 引擎和 ...

  6. docker 原理之 mount namespace(下)

    1. mount namespace mount namespace 通过隔离文件系统挂载点对隔离文件系统提供支持.使用 unshare 构造 mount namespace 如下: root@chu ...

  7. 项目使用 GlobalExceptionHandler 自定义异常 一

    博主原创,未经允许不得转载: 每个项目都有自己的一套异常类的定义.总结一下,项目中使用自定义异常比较好的封装. 1.定义项目中统一使用的异常类,用于捕获项目中的自定义异常等: package com. ...

  8. mysql之力扣数据库题目620有趣的电影优化记录

    闲着没事儿刷刷力扣的数据库题目,题目编号620:有趣的电影,下面是题目描述: 优化前的sql及执行时间: 优化后的sql及执行时间: 这里对筛选条件进行了优化: 1.select * 的查找效率要比逐 ...

  9. Memory Bist

    SRAMC主要是对SRAM进行控制 对于SRAM的逻辑,根据地址将数据存储到SRAM中,然后根据地址将SRAM中的数据读取出来 如何测试Memory,生产工艺原因造成的问题,采用DFT或者Bist测试 ...

  10. ONVIF网络摄像头(IPC)客户端开发—最简RTSP客户端实现

    前言: 网上对于RTSP协议客户端的表述和实现非常不清晰,在实际使用中,FFMPEG和live555这些软件已经实现了RTSP客户端和服务端的所有功能,但是它们并没有将RTSP协议独立出来,通过看li ...