【C语言学习笔记---内存函数】

C语言程序设计笔记---019

  • C语言进阶之内存函数
    • 1、memcpy函数
      • 1.1、模拟实现memcpy
    • 2、memmove函数
      • 2.1、模拟实现memmove函数
    • 3、memset函数
    • 4、memcmp函数
    • 5、结语

C语言进阶之内存函数

前言:
通过C语言进阶前篇的字符串函数的知识,继续C语言的内存函数学习。

/知识点汇总/
内存相关的函数
1.memcpy – strcpy —仅仅是操作字符串进行拷贝,而memcpy内存中的数据,不仅仅是操作字符
2.memmove
3.memset
4.memcmp — strcmp

1、memcpy函数

原型:void *memcpy( void *dest, const void src, size_t count ); ---- void 说明,兼容任意类型
头文件:<string.h>
功能:将源头内存的数据。拷贝到目标内存中
注意:与strncpy不同的是,参数num和count。一个是指需要拷贝的元素个数,一个是指需要拷贝的元素字节大小

#include <stdio.h>
#include <string.h>
int main()
{int arr1[10] = { 0 };int arr2[] = { 1,2,3,4,5 };memcpy(arr1, arr2, 20);//20 == 4*5int sz = sizeof(arr1) / sizeof(arr1[0]);for (int i = 0; i < sz; i++){printf("%d ", arr1[i]);}return 0;
}

1.1、模拟实现memcpy

#include <stdio.h>
#include <string.h>
#include <assert.h>//注意:void* 不能进行运算操作
//另外,这里必须使用(char*)进行操作,因为如果是其它类型就会造成数据上的丢失等问题 --- 联想类似于qsort一个个字节进行操作
void* my_memcpy(void* dest, const void* src, size_t sz)//sz拷贝多少个字节
{assert(dest && src);while (sz--)//以一个字节一个字节的拷贝{*(char*)dest = *(char*)src;dest = (char*)dest + 1;//注意:强制类型转换具备临时属性,所以需要(char*)dest+1来赋值保存数据,不能用dest++src =  (char*)src + 1;}
}int main()
{int arr1[10] = { 0 };int arr2[] = { 1,2,3,4,5 };my_memcpy(arr1, arr2, 20);//20 == 4*5for (int i = 0; i < 5; i++){printf("%d ", arr1[i]);}return 0;
}

扩展:memcpy对同一内存空间的操作问题

#include <stdio.h>
#include <string.h>
#include <assert.h>//注意:void* 不能进行运算操作
//另外,这里必须使用(char*)进行操作,因为如果是其它类型就会造成数据上的丢失等问题 --- 联想类似于qsort一个个字节进行操作
void* my_memcpy(void* dest, const void* src, size_t sz)//sz拷贝多少个字节
{assert(dest && src);void* ret = dest;while (sz--)//以一个字节一个字节的拷贝{*(char*)dest = *(char*)src;dest = (char*)dest + 1;//注意:强制类型转换具备临时属性,所以需要(char*)dest+1来赋值保存数据,不能用dest++src = (char*)src + 1;}return ret;
}int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };//my_memcpy(arr+2, arr, 20);//20 == 4*5//模拟的memcpy达不到预期的要求memcpy(arr + 2, arr, 20);//发现库函数的memcpy可以实现要求for (int i = 0; i < 5; i++){printf("%d ", arr[i]);}return 0;
}

小结
1.memcpy只能对不同空间内存之间的数据进行操作
即:不重叠内存的拷贝,可以使用memcpy,而重叠的内存空间则需要用memmove函数
2.库函数可以实现,标准规定:
以memcpy来实现不重叠的内存的拷贝,且要求能达到60即可,以memmobe来实现重叠内存的拷贝
3.但是,发现当前的编译环境下,memcpy同样能实现重叠内存的拷贝,远远满足60分的要求,100分
所以于编译环境相关,建议相应的功能交给适合的函数实现即可。

2、memmove函数

原型:void *memmove( void *dest, const void src, size_t count ); ---- void 说明,兼容任意类型
头文件:<string.h>
功能:将源头内存的数据。拷贝到目标内存中,且与memcpy相比可以拷贝同一空间的数据

#include <stdio.h>
#include <string.h>int main()
{//int arr1[10] = { 0 };//int arr2[] = { 1,2,3,4,5 };//memmove(arr1, arr2, 20);//20 == 4*5//int sz = sizeof(arr1) / sizeof(arr1[0]);//for (int i = 0; i < sz; i++)//{//	printf("%d ", arr1[i]);//}int arr[] = { 1,2,3,4,5,6,7,8,9,10};memcpy(arr+2, arr, 20);//20 == 4*5int sz = sizeof(arr) / sizeof(arr[0]);for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}

2.1、模拟实现memmove函数

#include <stdio.h>
#include <assert.h>void* my_memmove(void* dest, const void* src, size_t sz)
{assert(dest && src);char* ret = (char*)dest;if (dest < src)//从前向后拷贝{while (sz--){*((char*)dest) = *((char*)src);dest = (char*)dest + 1;src = (char*)src + 1;}}else//从后向前拷贝{while (sz--)//sz-- 先用再减,即先判断sz=20为真,用完后减1进入循环,此时sz=19{*((char*)dest + sz) = *((char*)src + sz);}}return ret;
}int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };my_memmove(arr + 2, arr, 20);//20 == 4*5//my_memmove(arr, arr + 2, 20);//20 == 4*5//my_memmove(arr, arr + 5, 20);//20 == 4*5int sz = sizeof(arr) / sizeof(arr[0]);for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}

3、memset函数

原型:void *memset( void *dest, int c, size_t count );
头文件:<string.h>
功能:是设置内存的,并且以字节为单位设置的

#include <stdio.h>
#include <string.h>int main()
{char arr[] = "hello world";memset(arr+6, 'H', 4);printf("%s\n", arr);return 0;
}

建议:以字节为单位设置的,所以更合适字符,但是设置为0可以是任意类型

4、memcmp函数

原型:int memcmp( const void *buf1, const void *buf2, size_t count );
头文件:<string.h>
功能:是比较两个内存块,并且是以字节为单位的方式进行比较的
返回值
*buf1 > *buf2 — 返回>0的值
*buf1 = *buf2 — 返回=0的值
*buf1 < *buf2 — 返回<0的值

#include <stdio.h>
#include <string.h>int main()
{//int arr1[] = { 1,2,3,4,5,6,7 };01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00//int arr2[] = { 1,2,3,7 };01 00 00 00 02 00 00 00 03 00 00 00 07 00 00 00//int ret = memcmp(arr1, arr2, 12);//精确到字节比较//printf("%d\n", ret);//0 --- 前12位相同//int arr1[] = { 1,2,3,4,5,6,7 };01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00//int arr2[] = { 1,2,3,7 };01 00 00 00 02 00 00 00 03 00 00 00 07 00 00 00//int ret = memcmp(arr1, arr2, 13);//精确到字节比较//printf("%d\n", ret);//-1 ---第十三位: 04 < 07int arr1[] = { 1,2,3,4,5,6,7 };//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00int arr2[] = { 1,2,3,0x11223304 };//01 00 00 00 02 00 00 00 03 00 00 00 04 33 22 11int ret = memcmp(arr1, arr2, 13);//精确到字节比较  --- 前13位相同 0//int ret = memcmp(arr1, arr2, 14);//精确到字节比较 --- 第14位 00 < 33 ---  -1printf("%d\n", ret);return 0;
}

5、结语

熟悉各个函数的使用有利于程序的可读性和效率,此篇笔记有误的地方请多多指教。
半亩方糖一鉴开,天光云影共徘徊。
问渠哪得清如许?为有源头活水来。–朱熹(观书有感)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/86214.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue+element plus 使用table组件,清空用户的选择项

<el-table ref"tableRef"> .... </el-table> <script lang"ts" setup> import { onMounted, reactive, ref, nextTick } from vue const clearBtn () > {console.log(清空用户的选择项)tableRef.value.clearSelection() } </scr…

基于Java的酒店管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

洛谷P5660:数字游戏 ← CSP-J 2019 复赛第1题

【题目来源】https://www.luogu.com.cn/problem/P5660https://www.acwing.com/problem/content/1163/【题目描述】 小 K 同学向小 P 同学发送了一个长度为 8 的 01 字符串来玩数字游戏&#xff0c;小 P 同学想要知道字符串中究竟有多少个 1。 注意&#xff1a;01 字符串为每一个…

docker alpine:3.16 root权限安装Anaconda3-2020.07-Linux-x86_64和jdk

首先查看系统版本: rootfv-az454-287:/tmp# uname -a Linux fv-az454-287 5.15.0-1046-azure #53~20.04.1-Ubuntu SMP Mon Aug 28 14:17:23 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux rootfv-az454-287:/tmp# grep NA /etc/os-release NAME"Ubuntu" PRETTY_NAME&q…

【VIM安装ctags cscope】

一、安装软件包 sudo passwd root sudo apt install cmake python2-dev python3-dev build-essential cmake flex bison -y sudo apt install universal-ctags cscope vim git -y sudo apt install python-is-python3 -y sudo apt-get install build-essential libncurses-dev…

算法 - 栈和队列

算法 - 栈和队列 算法 - 栈和队列 栈 1. 数组实现2. 链表实现 队列 栈 public interface MyStack<Item> extends Iterable<Item> {MyStack<Item> push(Item item);Item pop() throws Exception;boolean isEmpty();int size();}1. 数组实现 public class A…

在c#中使用CancellationToken取消任务

目录 &#x1f680;介绍&#xff1a; &#x1f424;简单举例 &#x1f680;IsCancellationRequested &#x1f680;ThrowIfCancellationRequested &#x1f424;在控制器中使用 &#x1f680;通过异步方法的参数使用cancellationToken &#x1f680;api结合ThrowIfCancel…

Docker Compose初使用

简介 Docker-Compose项目是Docker官方的开源项目&#xff0c;负责实现对Docker容器集群的快速编排。 Docker-Compose将所管理的容器分为三层&#xff0c;分别是 工程&#xff08;project&#xff09;&#xff0c;服务&#xff08;service&#xff09;以及容器&#xff08;cont…

【论文阅读 09】融合门控自注意力机制的生成对抗网络视频异常检测

2021年 中国图象图形学报 摘 要 背景&#xff1a; 视频异常行为检测是智能监控技术的研究重点&#xff0c;广泛应用于社会安防领域。当前的挑战之一是如何提高异常检测的准确性&#xff0c;这需要有效地建模视频数据的空间维度和时间维度信息。生成对抗网络&#xff08;GANs&…

langchain +gpt 报错 SSLError

解决版本2种 一加入下面代码: https://www.zhihu.com/question/588395420 import os os.environ["http_proxy"] "http://127.0.0.1:7890" os.environ["https_proxy"] "http://127.0.0.1:7890"二降低urllib3版本 urllib3 1.25.11错…

Stable Diffusion 系统教程 | 强大的ControlNet 控制网

2023年的2月13日&#xff0c;一款名叫ControlNet的插件横空出世&#xff0c;AI绘画变得更加可控 ControlNet直译过来很简单&#xff0c;就叫做控制网&#xff0c;开发者是一名华裔&#xff0c;毕业于苏州大学&#xff0c;目前在斯坦福做读博士一年级&#xff0c;大佬大佬&…

【lesson10】fork创建进程的现象解答

文章目录 fork现象fork问题 fork现象 我们先来看一段代码。 大家觉得这段代码的printf会打印几次&#xff1f; 结果&#xff1a; 我们可以清楚的看到&#xff0c;第二个printf打印了2次。 我们再来看一段不可思议的代码&#xff1a; 运行结果&#xff1a; 我们可以看到这r…

批量、在线学习, 参数、非参数学习

批量学习&#xff08;Batch Learning&#xff09;和在线学习&#xff08;Online Learning&#xff09; 批量学习 批量学习的概念非常容易理解&#xff0c;我们之前介绍的许多机器学习算法&#xff0c;如果没有特殊说明&#xff0c;都可以采用批量学习的方式。批量学习的过程通…

第35节——useLayoutEffect——了解

一、概念 组件挂载或渲染完成后调用。useLayoutEffect使用方法、所传参数和useEffect完全相同。 他们的不同点在于&#xff0c;你可以把useLayoutEffect等同于componentDidMount、componentDidUpdate&#xff0c;因为他们调用阶段是相同的。而useEffect是在componentDidMount…

iOS应用中的内存泄漏问题解决

解决iOS应用中的内存泄漏问题是非常重要的&#xff0c;因为内存泄漏可能导致应用变得缓慢或不稳定。以下是一些解决iOS内存泄漏问题的工具和方法&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 工具&…

SQLAlchemy Oracle Database 23c Free 集成之旅

SQLAlchemy & Oracle Database 23c Free 集成之旅 1. SQLAlchemy 是什么2. Oracle Database 23c Free 是什么3. 运行 Oracle Database 23c Free4. 学习 SQLAlchemy 统一教程4-1. 安装依赖库4-2. 建立连接 - 引擎4-3. 使用事务和 DBAPI4-3-1. 获取连接4-3-2. 提交更改4-3-3.…

【PowerQuery】Python自动刷新本地数据

Python数据刷新是开发爱好者和开发人员开发的PowerBI刷新模块进行数据刷新的手段,Python进行数据刷新是通过刷新PowerBI Desktop 的模式进行数据刷新。目前常用的Python的数据刷新模块是PbixRefresher,图为相关的模块和版本。 由于当前的脚本基于英文版本的PowerBI Desktop进…

【100天精通Python】Day69:Python可视化_实战:导航定位中预测轨迹和实际轨迹的3D动画,示例+代码

目录 1. 预测的3D轨迹和实际轨迹的动画图&#xff0c;同时动态更新 2 真值轨迹设置为静态的&#xff0c;预测轨迹不断更新 3 网格的三维坐标系有旋转运动&#xff0c;以此全方位展示预测轨迹和真值轨迹之间的空间关系 1. 预测的3D轨迹和实际轨迹的动画图&#xff0c;同时动态更…

vivo面试-Java

一、JAVA八股 1、Java实现线程的三种方式 (1) 继承 Thread 类&#xff1a; 创建一个新类&#xff0c;该类继承自Thread类&#xff0c;并重写run方法。然后创建该类的实例&#xff0c;并调用它的start方法来启动线程。 public class MyThread extends Thread {public void r…