内存操作函数

本文详细介绍了C语言中的四个内存操作函数:memcpy用于无重叠拷贝,memmove支持重叠区域拷贝,memset用于设置内存值,memcmp用于字节内容比较。通过模拟实现和实际例子展示了这些函数的使用方法和注意事项。
摘要由CSDN通过智能技术生成

1 memcpy函数

memcpy是内存操作函数,所在的头文件是#include<string.h>。

1.1memcpy功能

memcpy和strcpy有一点相似,但是strcpy只能进行字符串的拷贝,而它可以对各种类型都能进行拷贝,但是按字节去进行拷贝的,就比如你有2个整形数组:a1和a2;你想将a2里面四个元素拷贝进a1中,一个整形是4个字节,那么就要拷贝16个字节。

下面是他的这个函数的传参内容:

主要是三个参数:你要拷贝进的地址destination,你要拷贝内容的地址source和你要拷贝的字节数num。

例如:

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

 1.2模拟实现memcpy

我们模拟实现这个函数首先从他的传参入手,你传入的是两个地址和一个整形

然后因为可以是任意类型,所以我们用两个void*去接收,然后就一个字节一个字节的去拷贝,但是void*这种类型的指针不能直接解引用。所以我们先要进行强制类型转换成char*然后在进行拷贝。因为char类型是占一个字节,我们也是一个字节一个字节的拷贝,所以强转成字符型比较符合我们的要求。

代码:

void my_memcpy(void* s1, const void* s2, size_t num)     //void*的指针不能直接解应用
{
	while (num--)
	{
		*(char*)s1 = *(char*)s2;
		(char*)s1 = (char*)s1 + 1;
		(char*)s2 = (char*)s2 + 1;
	}
}
int main()
{
	int num;//拷贝的字节数
	int s1[20] = {1,2,3,4,5,6,7,9,0};
	int s2[20] = { 2,3,4,5,6,7,89 };
	scanf("%d", &num);
	my_memcpy(s1, s2, num);
	for (int i = 0; i <= 19; i++)
	{
		printf("%d", s1[i]);
	}
	return 0;
}

 特别注意:memcpy对于destination和source有重叠的是候拷贝的结果是未定义,但是在我们vs2022memcpy是可以完成当这两个内存空间有重叠的情况。但是我们有另外一个操作数可以完成这个重叠时候的情况。

2 memmove函数

2.1memmove的功能

memmove函数可以去进行当destination和source有重合时就有可以用这个函数去进行拷贝。

也是按照字节去进行拷贝的,他的功能比memcpy多一些,

他的传参和memcpy一样。

用法举例:

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

 2.2memmove的模拟实现

memmove因为可以进行重叠部分时拷贝的功能,所以他的模拟实现比memcpy稍微复杂一点。

这个重叠时候的情况还分为两种:

一种是destination在source的前面。

一种是source在destination的后面。

首先我们来讲第一种情况:

第一种情况是我们就要从前到后拷贝,这样你会将你没有进行拷贝的内容覆盖了,

第二种情况 就是需要我们要去从后往前拷贝才能不被覆盖掉。

void* my_memmove(void* destination, const void* source, int num)
{
	if (destination < source)//前到后
	{
		while (num--)
		{
			*(char*)destination = *(char*)source;
			destination = (char*)destination + 1;
			source = (char*)source + 1;
		}
	}
	else {//从后到前
		while (num--)
		{
			*((char*)destination + num)=*((char*)source+num);
		}
	}
}
int main()
{
	int s1[10] = { 1,2,3,4,5,6,7,8,9 };
	int num;
	scanf("%d", &num);
	my_memmove(s1 + 3, s1 + 2,num);
	for (int i = 0; i < 10; i++)
	{
		printf("%d", s1[i]);
	}
	return 0;
}

要注意的是当destination < source这一种情况是:

 destination = (char*)destination + 1;
   source = (char*)source + 1;

这两个语句不能写成destination++和source++;

因为我们这里的两个指针是void*

你要他自己去进行++的话,他不知道走多远,他没有具体类型,所以这里你要进行强转,再去进行++。

3 memset函数的使用

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

ptr是你想改换内容的地址,value是想要你要改成什么内容,num是改多少个字节。

例如:

#include <stdio.h>
#include <string.h>
int main ()
{
 char str[] = "hello world";
 memset (str,'x',6);
 printf(str);
 return 0;
}

 

4memcmp函数的使用

这个函数是进行字节内容进行比较的

从ptr1和ptr2指针指向的位置开始,向后的num个字节进行比较
如果相同返回0;
不相同返回:ptr1>ptr2的话返回大于零的数,小于就是返回小于零的数。
例如:
#include <stdio.h>
#include <string.h>
int main()
{
 char s1[] = "DWgaOtP12df0";
 char s2[] = "DWGAOTP12DF0";
 int n;
 n = memcmp(s1, s2, sizeof(s1));
 if (n > 0) 
 printf("'%s' is greater than '%s'.\n", s1, s2);
 else if (n < 0) 
 printf("'%s' is less than '%s'.\n", s1, s2);
 else
 printf("'%s' is the same as '%s'.\n", s1, s2);
 return 0;
}

 

 

  • 45
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

.小董

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值