c语言内存函数 memcap memove memset memcmp

一. memcpy 的使用和模拟

memcpy的使用

void* memcpy(void* destination, const void* soures, size_t num)	

memcpy的返回类型是 void* 类型, 接收的参数有三个,void* , const void*, size_t。
void* 表示了memcpy可以接受任何类型的地址,size_t 接收你想改的字节的个数

#include<string.h>
int main()
{
	char arr1[20] = "ABCD";
	char arr2[] = "AA";
	memcpy(arr1, arr2, 2);	
	//memcpy 接收了arr1, arr2 俩个字符的首地址, 表示memcpy从arr1的
	//首地址开始到arr2首地址复制俩个字节去 arr1
	printf("%s\n", arr);
	return 0;
}
//程序结果把arr1内容改变乘AACD
AACD//运行结果

函数memcpy返回的是 destination接收的首地址。
函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。
这个函数遇到/0不会停下来。
如果source和destination地址有任何的重叠,复制的结果都是未定义的。

模仿memcpy

首先设置memcpy函数的参数和类型,memcpy的参数都是void*,还有个size_t类型的参数,返回值也是void*

void* my_memcpy(void* dest, const void* sour, size_t num)
{
	void* re = dest;//因为要返回值是dest的地址
					//所以我们保留一下dest的首地址
	while(num--)//判断num的值,不为0进入循环
	{
		*(char*)dest = *(char)sour;//解引用把sour的内容赋值给*dest
								//因为传值过来num大小是按字节计算
								//所以我们移动一次需要移动一个字节
								//而char*移动一次的大小就是一个字节
								//我们强制转为char*类型
		dest = (char*)dest + 1;//每次赋值完,让dest, sour 移动一个字节
		sour = (char*)sour + 1;
	}
	return re;//返回了dest传过来的首地址
}

运行一下

#include<string.h>
int main()
{
	char arr1[20] = "ABCD";
	char arr2[] = "AA";
	my_memcpy(arr1, arr2, 2);	
	printf("%s\n", arr);
	return 0;
}
//程序结果把arr1内容改变乘AACD
AACD//运行结果

也是没有问题的

二. memmove 的使用和模拟

memmove 的使用

mommove 和 momcpy 区别就是 mommove源内存块可以和目标内存块是可以重叠的。

int main()
{
	int arr1[5] = { 1, 2, 3, 4 ,5 };
	memmove(arr1, arr1 + 3, 8);//这里俩个地址都是一样,
							   //mommove处理起来不会冲突
	int i = 0;
	while (i < 5)
	{
		printf("%d ", arr1[i++]);
	}
	return 0;
}
运行结果
45345

momove 的模拟

模拟 momove 主要是要解决一个问题源内存块可以和目标内存块冲突的问题

dest < sour
假设 1 2 3 4 5 要赋值 3 4 5 顶替 1 2 3 的位置变成 3 4 5 4 5
我
如果从后面开始一个一个复制过去先把 5 顶替 3 的位置 1 2 5 4 5
3 被顶替了直接就没了到时候要赋值 3 的 时候就找不到复制的就不是
我们想的结果了
那我们从只能从前往后赋值,这样的话刚好不会覆盖掉
dest > sour
但是又有一种情况 1 2 3 4 5 变成 1 2 1 2 3 如果从前往后一个一个复制的
话又覆盖掉 3 了这种情况就只能从后往前赋值
dest = sour
这种情况的从前往后,从后往前都可以,那我们只需要考虑俩种情况
一种是 dest < sour 要从前往后复制
一种是 dest > sour 从后往前赋值

void* my_memmove(const void* dest, const void* sour, size_t m)
{
	void* ret = (void*)dest;
	if (dest <= sour) //从前往后复制
	{
		while (m--)
		{
			*(char*)dest = *(char*)sour;
			dest = (char*)dest + 1;
			sour = (char*)sour + 1;
		}
	}
	else//从后往前
	{
		dest = (char*)dest + m - 1;//想到找到最后那位只
								//需要加上count - 1的值就能找到
		sour = (char*)sour + m - 1;
		while (m--)
		{
			*(char*)dest = *(char*)sour;
			dest = (char*)dest - 1;
			sour = (char*)sour - 1;
		}
	}
	return ret;
}
int main()
{
	int arr1[5] = { 1, 2, 3, 4 ,5 };
	my_memmove(arr1, arr1, 12);
	int i = 0;
	while (i < 5)
	{
		printf("%d ", arr1[i++]);
	}
	return 0;
}

三. memset 的函数的使用

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

void* memset(void* ptr, int value, size_t num);
返回值是 void*类型,返回 ptr 刚传过来的地址
prt 是要改变内存的地址
value 是想要改变的内容
num 是想要改变多少个字节
int main()
{
	int arr[5] = { 1, 2, 3, 4, 5, };
	memset(arr, 0, 20);// 把arr里面的元素全部改为 0 第一个参数 arr的地址,
					   // 第二个参数就是想要改变的内容,改0, 第三个就是大小改5个元素,
					   // 一个元素大小4个字节,就是要改20个字节
	int i = 0;
	while (i < 5)
	{
		printf("%d ", arr[i++]);
	}
	return 0;
}

运行程序
结果就是全部改成了0
在这里插入图片描述

四. memcmp的使用

int memcmp(const* void prt1, const void* prt2, size_t num);

比较从 prt1 和 prt2 指针指向的位置开始,向后num 个字节
如果 prt1 比较的那个字节比 prt2 小,返回一个 小于 0 的值
如果 prt1 比较的那个字节等于 prt2 ,返回一个等于 0 的值
如果 prt1 比较的那个字节比 prt2 大,返回一个 大于 0 的值

int main()
{
	char arr1[] = "ABCD";
	char arr2[] = "ABCd";
	int ret = memcmp(arr1, arr2, 4);
	if (ret > 0)
	{
		printf("arr1  > arr2\n");
	}
	else if (ret < 0)
	{
		printf("arr1  < arr2\n");
	}
	else
	{
		printf("arr1  = arr2\n");
	}
	return 0;
}

运行结果

arr1  < arr2

在ASCLL 码表中 小写比大写 大 32 所以结果正确。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值