部分内存函数

一、memcpy函数

 使用前需要 #include<string.h>

该函数最后会返回destination的地址;

函数memcpy从source的位置开始向后复制num个字节

并且该函数遇到\0不会停止复制

source和destinetion部分不能出现重叠部分,否则可能出问题

 -----------------------------------------------------------------------------------

对于该函数你可以对任意类型的数组进行拷贝和粘贴操作,因为形参部分是void*,可以接收任何类型的指针

经过简单的讲解,我们下面来模拟实现一下memcpy函数

​
​
#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memcpy(void* destination, const void* source, size_t num)
{
	void* ret = destination;
	assert(destination && source);
	while (num--)
	{
		*(char*)destination = *(char*)source; 
		destination = (char*)destination + 1;
		source = (char*)source + 1;
	}
	return ret;
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
	my_memcpy(arr + 2, arr, sizeof(int) * 2);
	for (int i = 0; i < 10; i++)
		printf("%d ", arr[i]);
}

​

​

通过一个字节一个字节地拷贝粘贴来进行操作

运行后结果为

符合要求

-------------------------------------------------------------------------------------------------------------------------------

            

注意   若想要达成像如图所示的效果,能否通过my_memcpy(arr+3,arr,sizeof(int)*4)进行操作,

答案是否定的

​
#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memcpy(void* destination, const void* source, size_t num)
{
	void* ret = destination;
	assert(destination && source);
	while (num--)
	{
		*(char*)destination = *(char*)source;
		destination = (char*)destination + 1;
		source = (char*)source + 1;
	}
	return ret;
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
	my_memcpy(arr + 3, arr, sizeof(int) * 4);
	for (int i = 0; i < 10; i++)
		printf("%d ", arr[i]);
}

​

我们原本期待打印出  打印出来的结果是    1 2 3 1 2 3 4 8 9 0   

但是实际结果是

   

这是因为该数组原来的4先被1拷贝粘贴后给覆盖了,所以后面作为source的第四个就变成了1,所以后面拷贝粘贴的也是1           

memcpy函数也存在这样的问题,所以说如果source部分和destination部分如果有重叠可能不会是我们想要的结果,memcpy是用来处理不重叠的内存拷贝

而这个时候memmove函数可以帮我们实现这个效果

但是在我自己使用的vs编译器上发现用memcpy这个函数也可以实现具有重叠部分的拷贝粘贴

这是为什么呢?

因为我们对memcpy函数的要求只是能够进行不重叠的拷贝粘贴就行了,但是vs编译器还实现了对重叠部分的拷贝粘贴

但是并不是说所有的编译器都是这样

所以说重叠的内存拷贝粘贴还是交给memmove函数

memmove函数不仅能实现重叠部分函数的拷贝粘贴,还能够实现没有重叠部分函数的拷贝粘贴

二、memmove函数

头文件和上面的一样

memmove对source和destination有重叠部分的函数进行拷贝粘贴实现

#include<stdio.h>
#include<string.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
	memmove(arr + 3, arr, sizeof(int) * 4);
	for (int i = 0; i < 10; i++)
		printf("%d ", arr[i]);
}

满足了我们刚才在讨论memcpy函数时的需求

------------------------------------------------------------------------------------------------------------------------

我们再模拟实现一下memmove函数

#include<stdio.h>
#include<string.h>
#include<assert.h
void* my_memmove(void* destination, const void* source, size_t num)
{
	void* ret = destination;
	assert(destination && source);
	if (destination < source)               /*这种情况从前往后复制粘贴,可以避免source里有些元素没有复制粘贴就被覆盖*/
	{
		*(char*)destination = *(char*)source;
		destination = (char*)destination + 1;
		source = (char*)source + 1;
	}
	else
	{
		while (num--)                        /*从后往前复制粘贴,可以避免source里有些元素没有复制粘贴就被覆盖*/
			*((char*)destination + num) = *((char*)source + num);
	}
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
	memmove(arr + 3, arr, sizeof(int) * 4);
	for (int i = 0; i < 10; i++)
		printf("%d ", arr[i]);
}

三、memcmp函数

memcmp函数是一个字节一个字节进行比较当

最后的num表示最多要比较的字节,也就是说如果在之前就比较出来了是可行的

mencmp函数比较时,第一个比第二个大,返回正数,第一个比第二个小,则返回负数,若相等,则返回0

​
#include<stdio.h>
#include<string.h>
int main()
{
	int i = 0;
	int arr1[10] = { 1,2,3,4,5,1,7,8,9,0 };
	int arr2[10] = { 1,2,3,4,5,257 };
	int a=memcmp(arr1, arr2,21 );
	printf("%d", a);
	return 0;
}

​

这两个数组前21个字节都是这个

一样所以运行后

---------------------------------------------------------------------------------------------------------------------------

​
​
#include<stdio.h>
#include<string.h>
int main()
{
	int i = 0;
	int arr1[10] = { 1,2,3,4,5,1,7,8,9,0 };
	int arr2[10] = { 1,2,3,4,5,257 };
	int a=memcmp(arr1, arr2,22 );
	printf("%d", a);
	return 0;
}

​

​

arr1前22个字节

arr2前22个字节

所以从第一个字节开始比,比到第22个字节arr2大于arr1的

所以运行结果

四、memset函数

memset函数就是将ptr指向及的向后的num个字节的内容改为value

比如

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = "hello world";
	memset(arr + 3, 'x', 5);
	printf("%s", arr);
	return 0;
}

结果是

但是注意memset函数千万不要像下面那样使用

#include<stdio.h>
#include<string.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7 };
	memset(arr, 1, 5);
	for (int i = 0; i < 7; i++)
		printf("%d ", arr[i]);
	return 0;
}

原本你想的是打印出来是1 1 1 1 1 6 7

可是实际结果是

分析一下

   

这里分别代表执行函数前后

发现这里是将arr前5个字节改为了1

所以说要记住memset是以字节为单位进行修改


小结

这是我对一些内存函数的简单介绍,如有问题欢迎大家的纠错批评

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值