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

}

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

相关推荐
mit6.8242 小时前
[实现Rpc] 通信类抽象层 | function | using | 解耦合设计思想
c++·网络协议·rpc
laimaxgg2 小时前
Qt常用控件之单选按钮QRadioButton
开发语言·c++·qt·ui·qt5
尼尔森系3 小时前
排序与算法:希尔排序
c语言·算法·排序算法
AC使者4 小时前
A. C05.L08.贪心算法入门
算法·贪心算法
冠位观测者4 小时前
【Leetcode 每日一题】624. 数组列表中的最大距离
数据结构·算法·leetcode
yadanuof4 小时前
leetcode hot100 滑动窗口&子串
算法·leetcode
可爱de艺艺4 小时前
Go入门之函数
算法
ox00804 小时前
C++ 设计模式-命令模式
c++·设计模式·命令模式
武乐乐~4 小时前
欢乐力扣:旋转图像
算法·leetcode·职场和发展
Blasit5 小时前
C++ Qt建立一个HTTP服务器
服务器·开发语言·c++·qt·http