内存操作函数(memset,memcmp,memcpy)的实现

在对这些内存操作时,这些函数首先,都是使用的是无类型指针,即泛型指针。其次,他们都是对字节进行操作的,因此这两点保证了他们可以对任何类型数据进行操作。 

一、memset内存的初始化,我们给出memset函数的声明·

void *memset( void *dest, int c, size_t count ); 
第一个参数 void *dest 起始位置。
第二个参数 int c 初始化为什么值,一般根据自己的情况进行初始化。
第三个参数 size_t count 字节数的大小,就是你要初始化的空间大小。

下来我们对这个memset()函数进行实现:

1、判断参数的有效性。

2、保护参数,因为最终你要返回一直指针所指位置以后的数据,我们就要进行保护参数。

3、这里我们要注意保护参数的同时要转换类型,对于空类型指针来说可以转换为任何类型的指针,因此这一就是我们为什么要用空类型指针。

4、就是进行初始化的工作。

void*  my_memset(void* dest, int c, size_t count)
{
	//判断参数有效性
	assert(dest != NULL);
	//保护参数
	char* p1= (char*)dest;//转换类型
	while (count-- != 0)
	{
		*p1++ = c;
	}
	return dest;
}
void main() 
{	int ar[10] = { 1,2,3,5,6,78,8,9,4 };
	my_memset(ar, 0, sizeof(ar));
	for (int i = 0; i < 10; ++i)
	{
		printf("%d", ar[i]);
	}
}

二、 memcmp  内存比较函

给出内存比较函数的声明

int memcmp( const void *buf1, const void *buf2, size_t count );

第一和第二个参数就是要比较的数据

第三个参数 size_t count 字节数的大小,就是你要比较的空间大小。

下来我们对这个memset()函数进行实现:

这里同样首先,要判断参数有效性,其次你要保护参数的同时进行类型转化,下来就是对数据进行比较。

int my_memcmp(const void* buf1, const void* buf2, size_t count)
{
	assert(buf1 != NULL && buf1 != NULL);
	char* p1 = (char*)buf1;
	char* p2 = (char*)buf2;
	while (count-- != 0)
	{
		if (*p1 - *p2 != 0)
			break;
		p1++;
		p2++;
	}
	return *p1-*p2;
}

void main()
{
	int ar[10] = { 1,2,3,4,6,78,8,9,4 };
	int br[18] = { 1,2,3,4,10,3,4,5,6,7,8,8 };
	int res=my_memcmp(ar, br, sizeof(int) * 6);
	printf("%d\n", res);
}

三、memcpy 内存拷贝函数,这个函数是重要而且复杂的函数,因此我们要特别注意。

使用这个函数我们就要考虑内存重叠的问题。那什么是内存重叠 ?

内存重叠就是当目标指针在原指针的后面而且你要拷贝的数据个数大于目标指针和原指针之间的距离,此时就会发生内存重叠。

 

 上面这种情况就发生了内存重叠。

下面我们给出这个函数的声明:

 void *memcpy( void *dest, const void *src, size_t count );

第一个参数就是目标指针所指的数据

第二个参数就是原指针所指的数据

第三个参数 size_t count 字节数的大小,就是你要拷贝到目标的空间大小。

下面我们对这个函数进行实现,在实现的时候我们就要考虑有内存重叠的情况,因此我们编的代码就要解决这个问题。

当发生内存重叠时,我们考虑从后向前拷贝,向目标指针和原指针分别加count+1;然后进行从后向前拷贝,每拷贝一个向前加一,从而解决内存重叠的问题。

// memcpy  内存拷贝函数将源指针指向的内容拷贝到目标指针
//很重要
//我们必须考虑有内存重叠的情况,如果有内存重叠的情况
//这里我们就要说明一下内存重叠的情况

void* my_memcpy(void* dest, const void* src, size_t count)
{
	assert(dest != NULL && src != NULL);
	char* p1 =(char*)dest;
	const char* p2 = (const char *) src;
	if (p2 >= p1 || p2 + count <= p1)
	{
		while (count-- != 0)
		{
			*p1++ = *p2++;
		}
	}
	else
	{
		//内存重叠,我们考虑从后向前拷贝
		p2 = p2 + count - 1;
		p1 = p1 + count - 1;
		while (count-- != 0)
		{
			*p1-- = *p2--;
		}
	}
	return dest;
}
void main()
{
	char* ar = "hellocpp";
	char br[18];
	my_memcpy(br, ar, strlen(ar)+1);
	printf("%s\n", br);

}

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
引用: 结果发现:memcpy在拷贝数据时与strcpy和strncpy不同的是memcpy遇到 '\0' 是不会停止拷贝到。 引用: 知识点4:memcpy()函数的模拟:void* my_memcpy(void* dst, const void* src, size_t count) { ... } 引用: 代码演示:memcpy(arr2, arr1, 6); memsetmemcpyC语言中的两个函数memset函数用于将一块内存区域的每个字节都设置为指定的值,而memcpy函数用于将一块内存区域的数据拷贝到另一块内存区域。 具体来说,memset函数的原型为void *memset(void *s, int c, size_t n),其中s是指向内存区域的指针,c是要设置的值,n是要设置的字节数。该函数会将s所指向的内存区域的每个字节都设置为c。 而memcpy函数的原型为void *memcpy(void *dest, const void *src, size_t n),其中dest是目标内存区域的指针,src是源内存区域的指针,n是要拷贝的字节数。该函数会将src所指向的内存区域的数据拷贝到dest所指向的内存区域。 需要注意的是,memcpy在拷贝数据时,不会像strcpy和strncpy那样遇到 '\0' 就停止拷贝,而是会一直拷贝下去直到拷贝完指定的字节数。这是memcpy与strcpy和strncpy的一个区别。 在引用中给出了一个自定义的my_memcpy函数的示例代码,该函数模拟了memcpy函数的功能。 在引用中给出了一个使用memcpy函数的示例代码,该代码将字符串"abc\0def"的前6个字节拷贝到另一个字符数组中。 综上所述,memsetmemcpyC语言中用于操作内存的两个函数,分别用于设置内存区域的值和拷贝内存区域的数据。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [内存函数:memcpy、memmove、memcmpmemset(超详细讲解,小白一看就懂!!!!)](https://blog.csdn.net/weixin_45031801/article/details/127481057)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

刘小小@

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

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

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

打赏作者

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

抵扣说明:

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

余额充值