C语言中的内存函数

1. memcpy使⽤和模拟实现
2. memmove使⽤和模拟实现
3. memset函数的使⽤
4. memcmp函数的使⽤
注:内存函数的头文件都是<string.h>

memcpy:实现两个指针内容的拷贝

如何使用?

可以看出memcpy函数需要接收的参数为void*,const void*,size_t。destination是指目标指针,source是指源头指针,而第三个参数size_t num是要拷贝过去的字节数(特别注意不是元素个数),结合起来看就是从内存的角度实现把source里 num个字节的内容 拷贝到destination中。

结合下面的例子品一下:

拷贝字符串

int main()
{
	char arr1[100] = "abcdefjhppq";
	char arr2[100] = "ENGLISH";
	memcpy(arr1,          arr2,       7 * sizeof(char));
	     //destination   source     num
	printf("%s\n", arr1);//返回arr1的首地址来打印字符串
	return 0;
}

拷贝整型

int main()
{
	int arr1[10] = {1,2,3,4,5,6,7,8,9,10};
	int arr2[5] = {100,200,300,400,500};
	memcpy(arr1, arr2, 5 * sizeof(int));
	//destination   source     num
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

模拟实现memcpy:

void* my_memcpy(void* dest, const void* sour, size_t num)
{
	char* ret = dest;//定义一个指针存放目标指针的首地址用于最后的返回值

	//num一进去是4个字节,然后减1。直到num=1先进去完成循环再自减为0,跳出去,执行循环4次。
	while (num)
	{
		*(char*)dest = *(char*)sour;//他俩都是void*型 不能直接解引用 所以强制类型转换

		(char*)dest=(char*)dest+1;
		//为何强转为char*?因为操作的num是以1个字节为单位,char*型指针每次刚好跳过1个字节
		//若强转成(int*)每次跳4个字节,如果我想操作奇数个字节就麻烦了
		(char*)sour=(char*)sour+1;

		num--;
	}
	return ret;
}
int main()
{
	char arr1[] = "abcdefjh";
	char arr2[] = "HAHEHO";
	my_memcpy(arr1, arr2, 4 * sizeof(char));
	printf("%s\n", arr1);//盼望得到:HAHEefjh
	return 0;
}

 完成!!

memmove:实现 有重叠内存空间的 指针的拷贝

对比刚刚的memcpy,前者实现的是  指向两块不同内存空间的指针  的内容的拷贝,并不期望它来完成有重叠空间的任务,例如实现一个字符串之间的拷贝:abcdefj 把efj拷贝到abc上变成 efjdefj。

而memmove就是用来实现上述功能的函数。

先来看如何使用它:

参数和返回值同memcpy一样。

看个例子来使用它:

int main()
{
	char arr[] = "abcdefjABCDEFJ";
	memmove(arr, arr + 7, 5*sizeof(char));
	printf("%s\n", arr);
	return;
}

模拟实现:

void* my_memmove(void* dest, const void* sour, size_t num)
{
	void* ret = dest;
	while (num--)
	{
		*(char*)dest = *(char*)sour;
		(char*)dest = (char*)dest + 1;
		(char*)sour = (char*)sour + 1;
	}
	return ret;
}

int main()
{
	int arr[10] = { 1,200,300,400,500,6,7,8,9,100 };
	my_memmove(arr, arr + 2, 3 * sizeof(int));
	
	//打印数组
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

那如果目标在源头之后呢?还能从两个数组的头部开始拷贝吗?

看下代码: 

void* my_memmove(void* dest, const void* sour, size_t num)
{
	void* ret = dest;
	while (num--)
	{
		*((char*)dest + num) = *((char*)sour + num);
		//从两个指针的末端开始拷贝,所以加num,从最后一个字节开始,随着num的减少向前移
	}
	return ret;
}
int main()
{
	int arr[10] = { 1,2,300,400,500,6,7,8,9,100 };
	my_memmove(arr + 2, arr, 3 * sizeof(int));
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

以上两种情况用if和else结合一下就很好了:

void* my_memmove(void* p1, const void* p2, size_t num)
{
	void* ret = p1;
	if (p1 < p2)
	{
		while (num--)
		{
			*(char*)p1 = *(char*)p2;
			p1 = (char*)p1 + 1;
			p2 = (char*)p2 + 1;
		}
	}

	else
	{
		while (num--)
		{
			*((char*)p1 + num) = *((char*)p2 + num);
		}
	}
	return ret;
}
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr+3, arr, 5 * sizeof(int));
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

memset:设置内存中的内容

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

ptr指向要修改的内容,value是你要填充的内容,num是value的字节数。

看下例子来使用它:

int main()
{
	char str[] = "hello world";
	memset(str, '*', 6);
	printf(str);
	return 0;
}

memcmp:比较从两个指针开始向后num个字节的内容

返回值如下:prt1<ptr2--<0 

                           =       --0

                           >       -->0

下例子使用它:

int main()
{
	char buffer1[] = "DWgaOtP12df0";
	char buffer2[] = "DWGAOTP12DF0";

	int n;

	n = memcmp(buffer1, buffer2, sizeof(buffer1));

	if (n > 0) 
		printf("'%s' is greater than '%s'.\n", buffer1, buffer2);
	else if (n < 0)
		printf("'%s' is less than '%s'.\n", buffer1, buffer2);
	else 
		printf("'%s' is the same as '%s'.\n", buffer1, buffer2);

	return 0;
}

以上就是我对C语言中的内存函数的理解,感谢观看~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值