C - 语言->内存函数

news2024/11/26 7:19:25

目录

系列文章目录

前言

1. memcpy使⽤和模拟实现

1.2 memcpy函数的模拟实现:

2. memmove 使⽤和模拟实现

2.1memmove的模拟实现:

3. memset 函数的使⽤

4. memcmp 函数的使⽤


系列文章目录


✅作者简介:大家好,我是橘橙黄又青,一个想要与大家共同进步的男人😉😉

🍎个人主页:橘橙黄又青_C语言,指针-CSDN博客


前言

学习c语言的只要内存函数及其模拟实现,掌握函数返回类型,并模拟。

正文开始了

1. memcpy使⽤和模拟实现

void * memcpy ( void * destination, const void * source, size_t num );

函数内容:作用:复制数据,和前面strcpy相似。返回类型:无返回

1.函数memcpy从source的位置开始 向后复制 num个 字节 的数据到destination指向的内存位置.
2.这个函数在遇到 '\0' 的时候并不会停下来.
3.如果source和destination有任何的重叠,复制的结果都是未定义的.
也就是说:c语言对memcpy的定义是对 不重复内存数据类型进行复制,举个例子:
arr[20] = {1, 2,3, 4, 5, 6, 7, 8}
memcpy(arr, arr+3, 4)//把arr[2]向后的4个字节复制到arr向后的4个字节

memcpy复制都是在同一个数组,内存重叠了,这样是错误的。

memcpy的正确使用例子,代码1:

#include <stdio.h>
#include <string.h>
int main()
{
     int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
     int arr2[10] = { 0 };
     memcpy(arr2, arr1, 20);//把arr前面4个整形拷贝到arr2中
     int i = 0;
     for (i = 0; i < 10; i++){
         printf("%d ", arr2[i]);
     }
     return 0;
}

输出结果:

1.2 memcpy函数的模拟实现:

#include <stdio.h>
#include <string.h>

void * my_memcpy ( void * dst, const void * src, size_t count)//以字节单位复制
{
     void * ret = dst;
     assert(dst);//断言是否为NULL
     assert(src);
     while (count--) {//搬运conut个字节
         *(char *)dst = *(char *)src;//void不能解引用,强制转换后,在解引用。
         dst = (char *)dst + 1;//det++;但是void类型不能++,所以可以写成(char*)dst++;但是一些编译器不支持,所以最好写成改代码这样。
         src = (char *)src + 1;
     }
 return(ret);//返回起始地址
}

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

那对于重叠的内存数据怎么解决呢?cy语言对于重叠的内存,交给memmove来处理。

2. memmove 使⽤和模拟实现

函数内容:

void * memmove ( void * destination, const void * source, size_t num );

函数内容:作用:复制数据。返回类型:无返回。

1.和memcpy的差别就是memmove函数处理的源内存块和⽬标内存块是可以重叠的。
2.如果源空间和⽬标空间出现重叠,就得使⽤memmove函数处理。
举例1:
#include <stdio.h>
#include <string.h>
int main()
{
     int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
     memmove(arr1+2, arr1, 20);//把12345,拷贝到arr1中的34567上。
     int i = 0;
     for (i = 0; i < 10; i++){
         printf("%d ", arr[i]);
     }
    return 0;
}

输出结果:

2.1memmove的模拟实现:

代码分析时有3种情况,待我慢慢给你们分析:

void* my_memmove(void* dst, const void* src, size_t count)
{
	void* ret = dst;
	if (dst <= src || (char*)dst >= ((char*)src + count)) {//从后面往前面复制,是第1.2种情况

		while (count--) {
			*(char*)dst = *(char*)src;
			dst = (char*)dst + 1;
			src = (char*)src + 1;
		}
	}
	else {//从前面往后面复制.第3种情况选择从前面往后面复制
		dst = (char*)dst + count - 1;
		src = (char*)src + count - 1;
		while (count--) {
			*(char*)dst = *(char*)src;
			dst = (char*)dst - 1;
			src = (char*)src - 1;
		}
	}
	return(ret);
}
#include <stdio.h>
#include <string.h>
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr1 + 2, arr1, 20);//把1234,拷贝到arr1中的3456上。
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

第1种情况:

第2种情况:

第3种情况:

分析第2种:

3. memset 函数的使⽤

函数内容:

void * memset ( void * ptr, int value, size_t num );

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

案例1:

#include <stdio.h>
#include <string.h>
int main ()
{
     char str[] = "hello world";
     memset (str,'x',6);//把str前面6个字节换成x
     printf(str);
     return 0;
}

输出结果:

这里我们给一个错误案例2:

#include <stdio.h>
#include <string.h>
int main()
{
	int arr[10] = { 0 };
	memset(arr, 1, 40);
	printf(arr);
	return 0;
}

输出结果:

总结:memset函数是以字节为单位来改的

4. memcmp 函数的使⽤

函数内容:

int memcmp ( const void * ptr1, const void * ptr2, size_t num );

功能:⽐较从ptr1和ptr2指针指向的位置开始,向后的num个字节。

返回类型:int,以strcmo相似。

案例1:

#include <stdio.h>
#include <string.h>
int main()
{
     char buffer1[] = "DWgaOtP12df0";
     char buffer2[] = "DWGAOTP12DF0";
     int 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.coloradmin.cn/o/1292074.html

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

相关文章

如何让软文更具画面感,媒介盒子分享

写软文这种带有销售性质的文案时&#xff0c;总说要有画面感&#xff0c;要有想象空间。只有针对目标用户的感受的设计&#xff0c;要了解用户想的是什么&#xff0c;要用可视化的描述来影响用户的感受&#xff0c;今天媒介盒子就和大家分享&#xff1a;如何让软文更具画面感。…

postgresql从入门到精通 - 第37讲:postgres物理备份和恢复概述

PostgreSQL从小白到专家&#xff0c;是从入门逐渐能力提升的一个系列教程&#xff0c;内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容&#xff0c;希望对热爱PG、学习PG的同学们有帮助&#xff0c;欢迎持续关注CUUG PG技术大讲堂。 第37讲&#…

HarmonyOS 开发 Java 与 ArkTS 如何抉择?

本文详细分析 Java 与 ArkTS 在 HarmonyOS 开发过程的区别&#xff0c;力求解答学员的一些困惑。 何为 HarmonyOS&#xff1f; 在讨论语言的差异时&#xff0c;我们先了解下什么是 HarmonyOS。华为官方是这么解释 HarmonyOS 的&#xff1a; “鸿蒙操作系统”特指华为智能终端…

2023本人最全的私有笔记分享:pip的基本命令和使用

23年12月1日最后更新。 选择的命令pip。至少都是在python 3.6以上的。 更多内容见&#xff1a;链接&#xff1a;https://pan.baidu.com/s/19mS5N9XJ_AotF20kUwSA3w?pwdp5kx 提取码&#xff1a;p5kx 3. Pip命令相关&#xff1a; 1、注意&#xff1a;所有的pip在命令窗口执…

网络监控:网络故障告警通知

网络警报是向网络管理员发出的指示&#xff0c;表明设备已达到其设置的阈值或面临任何性能异常&#xff0c;网络警报可以通过不同的渠道通知网络管理员&#xff0c;例如电子邮件、短信、松弛、网络警报等。 通过网络监控警报&#xff0c;可以快速了解网络问题&#xff0c;通过…

如何通过内网穿透实现无公网IP也能远程访问内网的宝塔面板

文章目录 一、使用官网一键安装命令安装宝塔二、简单配置宝塔&#xff0c;内网穿透三、使用固定公网地址访问宝塔 宝塔面板作为建站运维工具&#xff0c;适合新手&#xff0c;简单好用。当我们在家里/公司搭建了宝塔&#xff0c;没有公网IP&#xff0c;但是想要在外也可以访问内…

PD-1、BRAF和MEK联合抑制BRAFV600E结直肠癌癌症的2期试验

今天给同学们分享一篇文章“Combined PD-1, BRAF and MEK inhibition in BRAFV600E colorectal cancer: a phase 2 trial”&#xff0c;这篇文章发表在Nat Med期刊上&#xff0c;影响因子为82.9。 结果解读&#xff1a; MAPK抑制增强BRAF V600E CRC的免疫反应 作者之前在BRAF…

架构师-3.用户体系

系统提供了 2 种类型的用户,分别满足对应的管理后台、用户 App 场景。 1.AdminUser 管理员用户,前端访问 s-ui-admin-vue3管理后台,后端访问 /admin-api/** RESTful API 接口。 2.MemberUser 会员用户,前端访问 s-ui-user用户 App,后端访问 /app-api/** RESTful API 接口。…

元宇宙展厅:打破2D展示桎梏,构建沉浸式营销场景

随着智慧生活的理念出现&#xff0c;人们的生活方式以及社交方式都出现了很多变化&#xff0c;传统的实体展厅无法满足人们对于多元化、个性化的需求&#xff0c;3D元宇宙展厅结合VR、3D与AI技术&#xff0c;重新构建全新视觉效果&#xff0c;满足不同用户需求以及行业多样化沉…

客户端配置网络代理

Windows IDEA &#xff08;2021.1.3&#xff09;

看了无数文章,今天终于理解这些性能指标了!

如果要问性能测试里那种技术最难&#xff0c;相信很多人都会说出“性能分析”这四个字。确实是&#xff0c;性能测试的执行是比较简单的&#xff0c;难的是执行完成后&#xff0c;如何分析这些数据。如何从一大堆数据里分析哪些数据是优秀的&#xff0c;哪些数据是有问题的。这…

我有才打造知识付费小程序

一站式线上线下活动管理 为用户提供“精彩城市生活和人脉资源”。 在线活动提供创业、互联网、科技、投资、金融、教育、亲子、生活、聚会交友、医疗、设计、分享会、脱口秀、音乐演出等多种活动类型, 为职场白领提升技能、拓展人脉、聚会交友的首选平台。 为主办方提供“一…

JVM 运行时内存篇

面试题&#xff1a; 讲一下为什么JVM要分为堆、方法区等&#xff1f;原理是什么&#xff1f;&#xff08;UC、智联&#xff09; JVM的分区了解吗&#xff0c;内存溢出发生在哪个位置 &#xff08;亚信、BOSS&#xff09; 简述各个版本内存区域的变化&#xff1…

时间序列预测实战(二十五)PyTorch实现Seq2Seq进行多元和单元预测(附代码+数据集+完整解析)

一、本文介绍 本文给大家带来的时间序列模型是Seq2Seq&#xff0c;这个概念相信大家都不陌生了&#xff0c;网上的讲解已经满天飞了&#xff0c;但是本文给大家带来的是我在Seq2Seq思想上开发的一个模型和新的架构&#xff0c;架构前面的文章已经说过很多次了&#xff0c;其是…

宏工科技:电池装备高效交付“唯快不破”

面向TWh时代的锂电设备供应需求&#xff0c;锂电设备向标准化、模块化方向升级的趋势显现。 “近年来&#xff0c;宏工科技聚焦电池匀浆技术创新与规模化降本&#xff0c;通过电池匀浆工艺段的模块化探索与应用&#xff0c;从项目周期、成本、效率等多维度赋能电池前段制造高质…

微信小程序开发之原生小程序开发和uniapp开发的区别,两种开发方式语法上的区别

目前小程序开发有两种形式&#xff0c;分别是原生小程序开发和使用uniapp开发&#xff0c; uniapp和小程序原生开发都有各自的优缺点&#xff0c;开发者可以根据具体需求选择合适的开发方式。 一、两者区别如下&#xff1a; 编程语言&#xff1a;uniapp使用Vue语法编写应用程序…

高压放大器应用场景分析

高压放大器是一种重要的电子设备&#xff0c;其功能是将输入信号的电压幅度放大&#xff0c;以满足不同领域对于信号处理和放大的需求。下面安泰电子将对高压放大器在各个应用场景中的重要性进行深入分析&#xff0c;帮助大家更好地理解和使用高压放大器。 一、音频领域 音乐制…

Leo赠书活动-12期 【Java程序员,你掌握了多线程吗?】文末送书

Leo赠书活动-12期 【Java程序员&#xff0c;你掌握了多线程吗&#xff1f;】文末送书 ✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1…

静态住宅代理科普——实际应用场景以及如何配置?

住宅代理IP不仅是理论上的网络工具&#xff0c;它在多个实际应用场景中表现突出&#xff0c;极大地便利了用户的网络操作。接下来&#xff0c;将深入探讨住宅代理IP在市场调研、内容访问、社交媒体管理等方面的实际应用&#xff0c;揭示其在不同领域的实用价值。 ## 实际应用场…

无公网IP环境Windows系统使用VNC远程连接Deepin桌面

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;…