Bootstrap

内存操作函数(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);

}

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;