当前位置: 首页 > article >正文

C语言-内存函数详解

文章目录

    • 1. memcpy使用和模拟实现
    • 2. memmove使用和模拟实现
    • 3. memset函数的使用
    • 4. memcmp函数的使用


1. memcpy使用和模拟实现

返回类型和参数:

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

1.函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。
2.这个函数在遇到 ‘\0’ 的时候并不会停下来。
3. 如果source和destination有任何的重叠,复制的结果都是未定义的。
4.注意单位是字节
5.头文件:#include<string.h>

memcpy使用:

int main() {
	int arr[20] = { 0 };//目标数组
	int arr1[] = { 1,2,3,4,5 };//源数组
	memcpy(arr, arr1, 20);//20单位是字节
	for (int i = 0; i < 5; i++) {//拷贝完打印
		printf("%d ", arr[i]);
	}
	return 0;
}

运行结果:
在这里插入图片描述

memcpy模拟实现

1.我们创建一个返回类型和参数于memcpy函数相同的函数
2.因为memcpy函数拷贝的单位是字节,所以我们在拷贝是将类型转化为(char*)类型
3.通过循环来拷贝

代码实现:

void* mn_memcpy(void* p1, const void* p2, size_t n) {
	assert(p1);//判断是否为空指针,参数和类型memcpy一样
	assert(p2);
	while (n) {//控制拷贝多少个字节
		*((char*)p1) = *((char*)p2);//将void*转化为char*(一字节)
			((char*)p1)++; 
			((char*)p2)++;
		n--;//
	}
}
int main() {
	int arr[20] = { 0 };
	int arr1[] = { 1,2,3,4,5 };
	mn_memcpy(arr, arr1, 20);
	for (int i = 0; i < 5; i++) {//拷贝完打印
		printf("%d ", arr[i]);
	}
	return 0;
}

运行结果:
在这里插入图片描述

2. memmove使用和模拟实现

返回类型和参数:

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

1.和memcpy的差别就是memmove函数处理的源内存块和⽬标内存块是可以重叠的。
2. 如果源空间和⽬标空间出现重叠,就得使⽤memmove函数处理。
3. 单位是字节
4. 头文件:#include<string.h>

memmove 使用:

 int main() {
	int arr1[] = { 1,2,3,4,5 };
	memmove(arr1+1, arr1, 3*sizeof(int));
	for (int i = 0; i < 5; i++) {//拷贝完打印
		printf("%d ", arr1[i]);
	}
	return 0;
}

运行结果:
在这里插入图片描述
memmove模拟:

1.我们创建一个返回类型和参数于memmove函数相同的函数
2.因为memmove函数拷贝的单位是字节,所以我们在拷贝是将类型转化为(char*)类型
3.我们要分三种情况考虑,再通过循环拷贝

三种情况:
在这里插入图片描述

代码实现:

void* mn_memmove(void* p1, const void* p2, size_t n) {
	assert(p1);//判断是否为NULL
	assert(p2);
	if (p1 <= p2 || (char*)p1 >= (char*)p2 + n)//包含两种情况,直接按顺序拷贝
	{
		while (n) {
			*((char*)p1) = *((char*)p2);//将void*转化为char*(一字节)
						((char*)p1)++; //(char*)p1加加,字节加一
						((char*)p2)++;
					n--;
		}
	}
	else {//第三种情况 倒序拷贝
		p1 = (char*)p1 + n - 1;
		p2 = (char*)p2 + n - 1;
		while (n) {
			*((char*)p1) = *((char*)p2);
			((char*)p1)--;
			((char*)p2)--;
			n--;

		}
	}
}
int main() {
	int arr1[] = { 1,2,3,4,5,6,7,8,9,0 };
	mn_memmove(arr1+1, arr1, 3*sizeof(int));
	for (int i = 0; i < 10; i++) {//拷贝完打印
		printf("%d ", arr1[i]);
	}
	return 0;}

运行结果:
在这里插入图片描述

3. memset函数的使用

返回类型和参数

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

1.memset是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容。
2. 头文件:#include<string.h>

使用:

int main() {
	char arr[] = "qwert";
	memset(arr, '0', 3 * sizeof(char));
	printf("%s", arr);
	return 0;
}

运行结果:
在这里插入图片描述

4. memcmp函数的使用

返回类型和参数:

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

1.比较从ptr1和ptr2指针指向的位置开始,向后的num个字节
2. 头文件:#include<string.h>

返回值:
在这里插入图片描述
使用:

int main() {
	char arr[] = "qwert";
	char arr1[] = "abcdf";
	if (memcmp(arr, arr1))
		printf("arr>arr1");
	else
		printf("arr1>arr");
	return 0;
}

运行结果:
在这里插入图片描述

以上就是我的分享了,如果有什么错误,欢迎在评论区留言。
最后,谢谢大家的观看!


http://www.kler.cn/news/148499.html

相关文章:

  • qss文件里面指定是哪一个控件的样式
  • 电子学会C/C++编程等级考试2022年06月(三级)真题解析
  • Vue 定义只读数据 readonly 与 shallowReadonly
  • 软工2021上下午第六题(组合模式)
  • 1.Spring源码解析-ClassPathXmlApplicationContext
  • Oracle
  • 线性表之队列
  • 【Qt绘制仪表盘】
  • CentOS7.9虚拟机EDA环境,支持模拟集成电路、数字集成电路、数模混合设计全流程,包含工艺库
  • LeetCode(33)最小覆盖子串【滑动窗口】【困难】
  • java BASE64Encoder BASE64Decoder 废弃
  • 大数据机房迁移该按照什么步骤进行 |数据中心
  • 【Java学习笔记】73 - 正则表达式
  • 算法通关村-----数据流的中位数
  • 企业源代码防泄密的有什么痛点及难点?
  • 安装MySQL搭建论坛
  • 通过测试驱动开发(TDD)的方式开发Web项目
  • Rust UI开发(一):使用iced构建UI时,如何在界面显示中文字符
  • 项目问题总结
  • 华为OD机试真题-整数对最小和-2023年OD统一考试(C卷)
  • 简要介绍Spring原生框架与Spring是轻量级框架的原因
  • 原生DOM事件、react16、17和Vue合成事件
  • Git控制指令
  • C语言枚举的作用是什么?
  • Java中类的类型判断技巧以及没有无参构造函数时的应对策略。isInstance()方法解析
  • PTA:编程实现strncpy函数功能(C语言)
  • Docker笔记-Docker搭建最新版zabbix服务端(2023-07-31)
  • Android开源框架--Dagger2详解
  • PCL 计算点云图中任意两点的欧式距离
  • Drool 7 SpreadSheet Decision Template 笔记