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);

}

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

相关推荐
ALISHENGYA9 分钟前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
tianmu_sama10 分钟前
[Effective C++]条款38-39 复合和private继承
开发语言·c++
chengooooooo11 分钟前
代码随想录训练营第二十七天| 贪心理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和
算法·leetcode·职场和发展
jackiendsc18 分钟前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法
羚羊角uou25 分钟前
【C++】优先级队列以及仿函数
开发语言·c++
姚先生9729 分钟前
LeetCode 54. 螺旋矩阵 (C++实现)
c++·leetcode·矩阵
FeboReigns30 分钟前
C++简明教程(文章要求学过一点C语言)(1)
c语言·开发语言·c++
FeboReigns34 分钟前
C++简明教程(文章要求学过一点C语言)(2)
c语言·开发语言·c++
264玫瑰资源库1 小时前
从零开始C++棋牌游戏开发之第二篇:初识 C++ 游戏开发的基本架构
开发语言·c++·架构
游是水里的游1 小时前
【算法day20】回溯:子集与全排列问题
算法