C语言内存函数

目录

1.memcpy的使用和模拟实现

2.memmove的使用和模拟实现

3.memset函数的使用

4.memcmp函数的使用


c语言内存函数主要是针对内存块来处理的

内存函数的头文件同样是<string.h>

1.memcpy的使用和模拟实现

cpp 复制代码
void * memcpy ( void * destination, const void * source, size_t num );

mem------memmory------记忆------内存

memcpy------内存拷贝

memmove------内存移动

memset------内存设置

memcmp------内存比较

三个参数分别为目标空间的地址、源头、被拷贝的字节个数,返回的是目标空间的起始地址

cpp 复制代码
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[] = { 0 };
	//将arr1的34567拷贝放到arr2中
	memcpy(arr2, arr1 + 2, 20);
	return 0;
}

函数memcpy从source的位置开始向后赋值num个字节的数据到destination指向的内存位置

这个函数在遇到'\0'的时候并不会停下来

如果source和destination有任何的重叠,复制的结果都是未定义的

memcpy的模拟实现

cpp 复制代码
void* my_memcpy(void* dest, const void* src, size_t num)
{
	int i = 0;
	void* ret = dest;
	assert(dest && src);
	for (i = 0; i < num; i++)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest+1;//这里不用后置++的原因是强制转换是临时的,当你不用的时候++已经不是这种强制类型的
		src= (char*)src+ 1;
	}
	return ret;
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = { 0 };
	my_memcpy(arr2, arr1 + 2, 20);
	return 0;
}

当然有一种特殊的情况

cpp 复制代码
void* my_memcpy(void* dest, const void* src, size_t num)
{
	int i = 0;
	void* ret = dest;
	assert(dest && src);
	for (i = 0; i < num; i++)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memcpy(arr1+2, arr1, 20);
	return 0;
}

发现原本应该有的位置上并没有出现12345的情况而是像这种12121

原因是3的位置上拿了个1,4的位置上拿了个2,5再想拿3的位置上的时候结果出现了1就会出现这样循环往复的情况

所以我们得到的结论是memory函数不负责重叠内存的拷贝,只负责不重叠的内存

memmove解决的正是这种重叠内存的拷贝

2.memmove的使用和模拟实现

cpp 复制代码
void * memmove ( void * destination, const void * source, size_t num );
cpp 复制代码
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(arr1 + 2, arr1, 20);
	return 0;
}

memmove的模拟实现

像这种情况就是从前往后遍历

像这种情况就是从后往前遍历

像这种情况我们不难发现不管是从前往后遍历或者是从后往前遍历都是可以的,但是为了方便我们编写程序我们采用了从后往前遍历的统一格式

这里我们引入数组的概念来理解我们会发现,当dest<src的时候是从前往后遍历的 ,当dest>src的时候是从后往前遍历的 ,根据这个我们就可以来编写程序了

cpp 复制代码
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);
		}
	return dest;
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr1, arr1+2, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

这样我们就可以得到了通用的情况了

3.memset函数的使用

cpp 复制代码
void * memset ( void * ptr, int value, size_t num );

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

cpp 复制代码
int main()
{
	char arr[] = "hello world";
	memset(arr + 6, 'x', 5);
	printf("%s", arr);
	return 0;
}

这样我们就可以将world替换成五个x了

4.memcmp函数的使用
cpp 复制代码
int memcmp ( const void * ptr1, const void * ptr2, size_t num );

这个其实跟我们strncmp是类似的,但它是什么类型都能够进行比较

cpp 复制代码
int main()
{
	int arr1[] = { 1,2,3,4,5,6 };
	int arr2[] = { 1,2,3,5,6,7 };
	int ret=memcmp(arr1, arr2, 16);
	printf("%d", ret);

}

内存函数有很多,我们举例几个主要的就到这里了,欢迎大家来指正不足

相关推荐
selfsongs10 小时前
指针、内存管理、现代 C++ 特性
c++
可编程芯片开发10 小时前
基于MATLAB的PEF湍流风场生成器模拟与仿真
算法
罗西的思考10 小时前
【Agentic RL / 强化学习 / OPD】OpenClaw-RL 源码阅读笔记 --- (9)--- Reward Judging
人工智能·算法·机器学习
吃着火锅x唱着歌11 小时前
Effective C++ 学习笔记 条款37 绝不重新定义继承而来的缺省参数值
c++·笔记·学习
2401_8414956411 小时前
【数据结构】B+树
数据结构·数据库·c++·b+树·概念·结构·操作原理
小保CPP11 小时前
OCR C++ Tesseract按行识别字符
c++·人工智能·ocr·模式识别·光学字符识别
阿米亚波12 小时前
【C++】流式数据输入处理(不完全整理)
开发语言·c++·笔记
Mr.HeBoYan12 小时前
一次持续三天才出现的丢包故障——深入解析 DPDK Memory Ordering、rte_ring 与 CPU Memory Barrier (下)
linux·网络·算法·架构·dpdk
wabs66612 小时前
关于图论【深度优先搜索的理论基础】
算法·深度优先·图论
皓月斯语13 小时前
【C++基础】三目运算符
开发语言·数据结构·c++