c语言内存移动my_mommove();拷贝函数my_momcpy();设置函数my_momset();

内存拷贝,移动和设置这三个函数在实现中充分体现了void类型指针的特点,对与void指针有问题的可以戳无类型void*指针的几大特性查看。
下来是我模拟实现的内存操作函数

1. 内存移动(也可用于内存拷贝,且避免了内存重叠带来的缺陷)

函数原型:void * memmove(void * _Dst, const void * _Src, size_t _Size);
参数说明:_Dst指针为目标指针; _Src为源指针;_Size为移动的距离

void* my_memove(void* dest, const void* src, size_t count)
{
	assert(dest&&src);
	char *tmp_dest = (char*)dest;
	char *tmp_src = (char*)src;
	if (dest<=src||(char*)dest>=(char*)src+count)//不会出现内存重叠,从低地址开始拷贝
	{
		while (count--)
		{
			*tmp_dest++ = *tmp_src++;
		}
	}
	else//为避免内存重叠带来的缺陷,从高地址拷贝
	{
		tmp_dest = tmp_dest + count - 1;
		tmp_src = tmp_src + count - 1;
		while (count--)
		{
			*tmp_dest--= *tmp_src--;
		}
	}
	return dest;
}

2. 拷贝函数(有可能会出现内存重叠的缺陷)

由 _Src指向地址为起始地址的连续count个字节的数据复制到以_Dst指向地址为起始地址的空间内。 _Src和_Dst两者所指向的地址不能有重叠,不然会出现内存重叠,拷贝不成功
函数原型:void *memcpy(void * _Dst, const void * _Src,size_t _Size);
参数说明:_Dst指针为目标指针; _Src,为源指针; _Size为拷贝的字节长度

#include
#include
struct Student
{
	char s_id[20];
	char s_name[20];
	char s_sex;
	int age;
};
void* my_memcpy(void* dest, const void* src, size_t count)
{
	assert(src != nullptr&&dest != nullptr);
	//判断dest指针和src指针是否为空,若为空抛出异常
	char* tmp_dest = (char*)dest;
	const char* tmp_src = (const char*)src;
	//将指针dest和指针src由void强转为char,
	//使得每次均是对内存中的一个字节进行拷贝
	while (count--)
		*tmp_dest++ = *tmp_src++;
	return dest;
}
int main()
{
	int ar[10] = { 12, 23, 34, 45, 56, 67, 78, 89, 90, 100 };
	int ar1[10];
	Student s1;
	Student s = { "20186787", "dasyi", 'm', 43 };
	my_memcpy(ar1, ar, sizeof(ar));
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", ar1[i]);
	}
	printf("\n");
	my_memove(ar1, ar, sizeof(ar));
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", ar1[i]);
	}
	printf("\n");
	my_memcpy(&s1, &s, sizeof(s1));
	printf("%s %s %c %d\n", s1.s_name, s1.s_id, s1.s_sex, s1.age);
	my_memove(&s1, &s, sizeof(s1));
	printf("%s %s %c %d\n", s1.s_name, s1.s_id, s1.s_sex, s1.age);
	return 0;
}

拷贝和移动的测试结果:c语言内存移动my_mommove();拷贝函数my_momcpy();设置函数my_momset();_第1张图片

3. 设置函数(初始化内存)

函数原型:void * memset(void * _Dst, _ int _Val, _ size_t _Size);
参数说明:_Dst指针为目标指针;_Val为内存中设置的值; _Size为设置的内存长度

void *my_memset(void *sd, int val, int n)
{
	if (NULL == sd || n < 1)return sd;
	char *tmp = (char *)sd;
	while (n--)
	{
		*tmp++ = (char)val;
	}
	return sd;
}
int main()
{
	char ar[10];
	int br[10];
	my_memset(br, 1, 40);
	for (int i = 0; i < 10; i++)
	{
		printf("%x\n",br[i]);
	}
	return 0;
}

测试结果:每个字节都为valc语言内存移动my_mommove();拷贝函数my_momcpy();设置函数my_momset();_第2张图片
内存移动函数和内存拷贝函数应用于内存增容。步骤如下:
1,重新分配大空间给同类型指针p。
2,将数据复制进新空间,然后将原来指针(t.data)j解放出来,即free(t.data);t.data=NULL;
3,将内存容量更新

bool Inc_Size(Seqlist&t)
{
	//t.data = (Elemtype *)realloc(t.data, sizeof(Elemtype)*(GetCapcity(t)*2));
	Elemtype*p = (Elemtype *)malloc(sizeof(Elemtype)*GetCapcity(t)* 2);
	if (t.data)
	{
		for (int i = 0; i < t.cursize; i++)
		{
			memcpy(p, t.data, sizeof(t.data));
		}
		free(t.data);
		t.data = NULL;
		t.data = p;
		t.maxsize = GetCapcity(t);
		return true;
	}
	else
	{
		return  false;
	}
}

你可能感兴趣的:(c语言---基础)