【零基础C语言】内存函数

前言:

我们之前学过strcpy,strcmp等等函数,他们可以拷贝字符串和比较字符串等等,那么有没有什么函数不光可以拷贝字符串还可以拷贝其他的数据呢,答案就是内存函数。

相较于字符串函数,内存函数可以拷贝的数据类型不受限制,故名思意,内存函数就是直接操作内存块的,因此任何类型的数据都可以进行操作,那么接下来我们需要学习的内存函数有memcpy,memmove,memset,memcmp。

memcpy

memcpy函数是一个内存拷贝函数,它可以将一块内存的数据拷贝给另一块内存,以下是它的函数原型: 

 该函数存在三个参数:

  1. dest:指向目标内存,简单说就是我们需要拷贝的数据存放的对象,比如我们像把数组1的数据拷贝给数组2,那么数组2就是拷贝的目标
  2. src:指向拷贝的来源,就是我们数据拷贝的来源,借用上面的例子就是数组1
  3. num:需要我们传入拷贝的内存大小,以字节为单位,比如说我们要拷贝一个int类型,那么num就需要传入4,或者sizeof(int)。

函数使用代码展现: 

// 内存函数 
// memcpy 
int main()
{// 来源数组1int arr1[] = { 0,1,2,3,4,5,6,7,8,9,10 };// 目标数组2int arr2[20] = { 0 };// 拷贝memcpy(arr2, arr1, 11 * sizeof(int));// 打印for (int i = 0; i < 20; i++){printf("%d ", arr2[i]);}return 0;
}

运行结果: 

这边注意我们拷贝的目标数组的容量一定要大于或者等于拷贝数据的大小,否则会出现错误。

 了解了使用方法后,让我们来自己实现这个函数的功能把。

函数分析: 

 通过函数模型知道我们也需要dst,src指针指向目标和来源,num传入拷贝的大小(以字节为单位)。

void* my_memcpy(void* dst, const void* src, size_t num)
{void* ret = dst;while (num--){*(char*)dst = *(char*)src; // 用char*进行强转保障每次的拷贝是一个字节// 建议写法1,不可以直接++// 写法1/*dst = (char*)dst + 1;src = (char*)src + 1;*/// 写法2((char*)dst)++;((char*)src)++;}return ret;
}

 memmove

memmove函数的使用方法和功能和memcpy基本一致,唯一有区别的是,如果按照我们上面实现memcpy函数的方法,我们是无法实现内存重叠的拷贝的,什么是内存重叠呢,我们来看下面一段代码: 

int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };my_memcpy(arr+2, arr, 5 * sizeof(int));for (int i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}

 我们自己拷贝给自己,arr代表数组首元素地址,arr+2指向的就是3,我们需要将1,2,3,4,5,从3的位置拷贝上去。

 最后的拷贝如上图,但是实际我们运行时如下图。

 因为拷贝的时候都是从头到尾,会发生覆盖问题,为了解决这样内存块重叠拷贝的问题,推出了memmove函数,当然现在在VS上的memcpy也可以解决这样的问题,但是涉及内存块重叠拷贝还是建议使用memmove函数。

函数原型: 

 该函数存在三个参数:

  1. dest:指向目标内存,简单说就是我们需要拷贝的数据存放的对象,比如我们像把数组1的数据拷贝给数组2,那么数组2就是拷贝的目标
  2. src:指向拷贝的来源,就是我们数据拷贝的来源,借用上面的例子就是数组1
  3. num:需要我们传入拷贝的内存大小,以字节为单位,比如说我们要拷贝一个int类型,那么num就需要传入4,或者sizeof(int)。

 函数使用代码展现:

int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };memmove(arr + 2, arr, 5 * sizeof(int));for (int i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}

 运行结果: 

 代码实现:

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

 memset

 memset是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容

int main ()
{
char str[] = "hello world";
memset (str,'x',6);
printf(str);
return 0;
}

 因为是以每一个字节取设置内存,对于其他存储高于一个字节的类型只能初始化,不可以设置其他的值,会产生错误:

int main()
{int arr[10];memset(arr, 0, 10*sizeof(int));for (int i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}

int main()
{int arr[10];memset(arr, 1, 10*sizeof(int));for (int i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}

 

memcmp 

⽐较从ptr1和ptr2指针指向的位置开始,向后的num个字节,内存函数的比较也是一个字节一个字节的比较。

函数原型:

#include <stdio.h>
#include <string.h>
int main()
{
char buffer1[] = "DWgaOtP12df0";
char buffer2[] = "DWGAOTP12DF0";
int n;
n = memcmp(buffer1, buffer2, sizeof(buffer1));
if (n > 0)
printf("'%s' is greater than '%s'.\n", buffer1, buffer2);
else if (n < 0)
printf("'%s' is less than '%s'.\n", buffer1, buffer2);
else
printf("'%s' is the same as '%s'.\n", buffer1, buffer2);
return 0;
}

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

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

相关文章

赎金信[简单]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给你两个字符串&#xff1a;ransomNote和magazine&#xff0c;判断ransomNote能不能由magazine里面的字符构成。如果可以&#xff0c;返回true&#xff1b;否则返回false。magazine中的每个字符只能在ransomNote中使用一次。 示例 …

DPDK实践之(1)dpdk基础使用

DPDK实践之(1)dpdk基础使用 Author: Once Day Date: 2024年5月19日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文档可参考专栏&#xff1a;Linux基础知识_Once…

C语言 | Leetcode C语言题解之第109题有序链表转换二叉搜索树

题目&#xff1a; 题解&#xff1a; int getLength(struct ListNode* head) {int ret 0;while (head ! NULL) {ret, head head->next;}return ret; }struct TreeNode* buildTree(struct ListNode** head, int left, int right) {if (left > right) {return NULL;}int …

Mac维护神器CleanMyMac X成为你的苹果电脑得力助手

在数字化时代&#xff0c;Mac电脑已成为众多用户的首选。然而&#xff0c;随着频繁的使用和数据量的日益增长&#xff0c;许多Mac用户面临着系统杂乱、存储空间不足以及隐私保护等问题。幸运的是&#xff0c;"CleanMyMac X"这款优化和清理工具应运而生&#xff0c;它…

ROCm上情感分析:使用循环神经网络

15.2. 情感分析&#xff1a;使用循环神经网络 — 动手学深度学习 2.0.0 documentation (d2l.ai) 代码 import torch from torch import nn from d2l import torch as d2lbatch_size 64 train_iter, test_iter, vocab d2l.load_data_imdb(batch_size)class BiRNN(nn.Module):…

java抽象类,接口,枚举练习题

第一题&#xff1a; 答案&#xff1a; class Animal{//成员变量protected String name;protected int weight;//构造方法public Animal(){this.name"refer";this.weight50;}public Animal(String name,int weight){this.namename;this.weightweight;}//成员方法publ…

Bugku Crypto 部分题目简单题解(四)

目录 python_jail 简单的rsa 托马斯.杰斐逊 这不是md5 进制转换 affine Crack it rsa python_jail 启动场景 使用虚拟机nc进行连接 输入print(flag) 发现报错&#xff0c;经过测试只能传入10个字符多了就会报错 利用python中help()函数&#xff0c;借报错信息带出flag变…

【力扣刷题笔记第三期】Python 数据结构与算法

先从简单的题型开始刷起&#xff0c;一起加油啊&#xff01;&#xff01; 点个关注和收藏呗&#xff0c;一起刷题鸭&#xff01;&#xff01; 第一批题目 1.设备编号 给定一个设备编号区间[start, end]&#xff0c;包含4或18的编号都不能使用&#xff0c;如&#xff1a;418、…

java抽象类和接口知识总结

一.抽象类 1.啥是抽象类 用专业语言描述就是&#xff1a;如果一个类中没有包含足够的信息来描绘一个具体的对象&#xff0c;这样的类就是抽象类 当然这话说的也很抽象&#xff0c;所以我们来用人话来解释一下抽象类 抛开编程语言这些&#xff0c;就以现实举例&#xff0c;我…

每日练习之排序——链表的合并;完全背包—— 兑换零钱

链表的合并 题目描述 运行代码 #include<iostream> #include<algorithm> using namespace std; int main() { int a[31];for(int i 1;i < 30;i)cin>>a[i];sort(a 1,a 1 30);for(int i 1;i < 30;i)cout<<a[i]<<" ";cout&…

Mysql之Innodb存储引擎

1.Innodb数据存储 innodb如今能够做到mysql的默认数据存储引擎&#xff0c;肯定有着其好处的&#xff0c;那么innodb有什么好处呢? 1. 当意外断电或者重启&#xff0c; InnoDB 能够做到奔溃恢复&#xff0c;撤销没有提交的数据 2.InnoDB 存储引擎维护自己的缓冲池&#xff0c…

医院挂号就诊系统的设计与实现

前端使用Vue.js 后端使用SpiringBoot MyBatis 数据使用MySQL 需要项目和论文加企鹅&#xff1a;2583550535 医院挂号就诊系统的设计与实现_哔哩哔哩_bilibili 随着社会的发展&#xff0c;医疗资源分布不均&#xff0c;患者就诊难、排队时间长等问题日益突出&#xff0c;传统的…

Hadoop3:HDFS的Fsimage和Edits文件介绍

一、概念 Fsimage文件&#xff1a;HDFS文件系统元数据的一个永久性的检查点&#xff0c;其中包含HDFS文件系统的所有目 录和文件inode的序列化信息。 Edits文件&#xff1a;存放HDFS文件系统的所有更新操作的路径&#xff0c;文件系统客户端执行的所有写操作首先 会被记录到Ed…

二叉树的链式结构

1.二叉树的遍历 2.二叉树链式结构的实现 3.解决单值二叉树题 1.二叉树的遍历 1.1前序&#xff0c;中序以及后序遍历 二叉树的遍历是按照某种特定的规则&#xff0c;依次对二叉树的结点进行相应的操作&#xff0c;并且每个结点只操作一次。 二叉树的遍历有这些规则&#xff…

主流电商平台商品实时数据采集API接口||抖音电商数据分析实例|可视化

— 1 — 抖音电商数据【抖音电商API数据采集】分析场景 1. 这里&#xff0c;我们选择“伊利”这个品牌作为案例进行分析&#xff0c;在短短的4个月里&#xff0c;从最初每月营收17.07万&#xff0c;到6月份达到了2485.54 万&#xff0c;伊利的牛奶&#xff0c;有点牛&#xff…

Spring 对 Junit4,Junit5 的支持上的运用

1. Spring 对 Junit4,Junit5 的支持上的运用 文章目录 1. Spring 对 Junit4,Junit5 的支持上的运用每博一文案2. Spring对Junit4 的支持3. Spring对Junit5的支持4. 总结&#xff1a;5. 最后&#xff1a; 每博一文案 关于理想主义&#xff0c;在知乎上看到一句话&#xff1a;“…

Xline社区会议Call Up|在 CURP 算法中实现联合共识的安全性

为了更全面地向大家介绍Xline的进展&#xff0c;同时促进Xline社区的发展&#xff0c;我们将于2024年5月31日北京时间11:00 p.m.召开Xline社区会议。 欢迎您届时登陆zoom观看直播&#xff0c;或点击“阅读原文”链接加入会议&#xff1a; 会议号: 832 1086 6737 密码: 41125…

通过cmd命令行使用用3dmax自带的vray渲染

有时调试需要使用vray渲染vrscene文件看效果&#xff0c;只装有3dmax下可以使用自带vray渲染&#xff0c;在3dmax的渲染日志里面看自带引擎路径 使用命令行进入到此目录 执行命令指定vr文件即可看到效果&#xff0c;如&#xff1a;vray.exe -sceneFile“C:\test15\202405241…

Cesium与Three相机同步(2)

之前实现了将Three相机同步到Cesium相机Cesium与Three相机同步(1)-CSDN博客 现在是将Cesium相机同步到Three相机,从而实现了相机双向同步。 <!DOCTYPE html> <html lang="en"><head><title>three.js webgl - orbit controls</title&g…

【教学类-58-03】黑白三角拼图03(4*4宫格)总数算不出+随机抽取10张

背景需求&#xff1a; 【教学类-58-01】黑白三角拼图01&#xff08;2*2宫格&#xff09;256种-CSDN博客文章浏览阅读318次&#xff0c;点赞10次&#xff0c;收藏12次。【教学类-58-01】黑白三角拼图01&#xff08;2*2宫格&#xff09;256种https://blog.csdn.net/reasonsummer/…