C语言内存函数

memory

n.记忆力,记性;记忆,回忆;(计算机存储器的)存储量;(计算机的)存储器;对死者的记忆;记忆所及的时间(或范围)。

什么是C语言内存函数呢?

        C语言内存函数是指对内存空间块的数据进行操作的函数,都在string.h这个头文件里,下面我们为大家介绍以下4个内存函数:

函数作用
memcpy拷贝源内存块的n个字节的数据到目标内存块,空间不可重叠
memmove拷贝源内存块的n个字节的数据到目标内存块,空间可重叠
memset对目标内存块的n个字节进行设置
memcmp比较两个内存块对应的数据

1.memcpy函数

(1).函数定义

void * memcpy ( void * destination, const void * source, size_t num );
  • void* destination             目标空间的地址,目标空间数据类型位置,使得指针类型未知,故而都使用void*类型适用任何类型数据。
  • const void * source         源空间的地址,只对源空间的数据做拷贝不做修改,故const
  • void*                               返回void*类型的地址是由于目标空间的指针类型未知。
  • size_t num                     无符号类型的num,拷贝字节的大小/数量

(2).函数作用

  • 从source所指向的位置开始拷贝num个字节的数据到destination所指向的空间里。
  • 使用memcpy函数时,source所指向的空间与destination所指向的空间不可重叠
  • 为了避免溢出,目的参数和源参数所指向的数组的大小至少为num字节。

(3).函数使用

(4).模拟实现

void* my_memcpy(void* p1, const void* p2, size_t num)
{
    //memcpy不拷贝重叠空间的数据,就当作两个独立空间处理
	void* ret = p1;
	while (num)//拷贝num次
	{
		//(char*)p1++;
		//((char*)p1)++;//为啥加个括号p1就从void*转为char*
		*(char*)p1 = *(char*)p2;//void*不能操作,转char*一个字节地拷贝
		//强制类型转换只是对数据的类型转换,不会对变量本身转换,p1本身还是void*
		((char*)p1)++;
		((char*)p2)++;
		num--;
	}
	return ret;//返回目标空间的地址
}
测试

发现问题:(char*)p1++和((char*)p)++的区别

操作符含义优先级
()括号1
++自加加2
(类型)强制类型转换3

"(类型)"这个操作符的优先级比++低不加括号++会先与p结合,而p是void*类型,不能被操作,所以要再加括号保证强制类型转换的优先级比++高,先将void*转为char*,就可以++操作了

2.memmove函数

(1).函数定义

void * memmove ( void * destination, const void * source, size_t num );
  • void* destination             目标空间的地址,目标空间数据类型位置,使得指针类型未知,故而都使用void*类型适用任何类型数据。
  • const void * source         源空间的地址,只对源空间的数据做拷贝不做修改,故const
  • void*                               返回void*类型的地址是由于目标空间的指针类型未知。
  • size_t num                      无符号类型的num,拷贝字节的大小/数量

(2).函数作用

  • 从source所指向的位置开始拷贝num个字节的数据到destination所指向的空间里。
  • 使用memcpy函数时,source所指向的空间与destination所指向的空间可重叠
  • 为了避免溢出,目的参数和源参数所指向的数组的大小至少为num字节。

(3).函数使用

(4).模拟实现

分析:

void* my_memmove(void* p1, const void* p2, size_t num)
{
    if(p1==p2)//相等的话,直接返回p1的地址
    	return p1;
	char* ret = p1;
	//重叠部分先拷贝,就能防止拷贝数据被改变
	if(p1 < p2)//重叠部分在源空间的前部分,从前向后拷贝
	{
		while (num)
		{
			*(char*)p1 = *(char*)p2;
			((char*)p1)++;
			((char*)p2)++;
			num--;
		}
	}
	if (p1 >= p2)//重叠部分在源空间的后部分,从后向前拷贝
	{
		while (num)
		{
			*((char*)p1+num) = *((char*)p2+num);
			num--;
		}
	}
	//独立的话随便,这里已经满足了,p1在前就向上面一样用前->后,在后就向上面一样用后->前。
	return ret;
}
测试

3.memset函数

(1).函数定义

void * memset ( void * ptr, int value, size_t num );
  •  void* ptr             需要填充数据的内存空间的地址,由于数据类型未知,使得指针类型未知,故而都使用void*类型适用任何类型数据。
  • int value              value为需要填充数据的值,int类型进行接受传递,在函数中int的数据会转换为unsigned char类型的数据进行填充因为每次填充内存单元,所以都是一个字节的大小的数据。
  • 其实value接收的就是字符的ASCII码值
  • size_t num          无符号类型的num,填充数据的大小/数量。
  • void*                   函数返回的是ptr一开始指向空间的起始地址。

(2).函数作用

        从ptr所指向的内存空间开始依次向后填充num个value值。

(3).函数使用

(4).模拟实现

void* my_memset(void* ptr, int value, size_t num)
{
	char* ret = ptr;//返回的起始地址
	while (num--)//进行num次填充
	{
		*((char*)ptr)++ = (unsigned char)value;//要把int类型的数据转unsigned char类型再赋值,再++
	}
	return ret;
}

4.memcmp函数

(1).函数定义

int memcmp ( const void * ptr1, const void * ptr2, size_t num );
  • ptr1和ptr2两个指针都是用于比较的,不会被修改的,所以用const修饰,以免出现书写错误,void*是不知道内存空间的数据类型,进而不知道指针类型,所以用void*接收。
  • 比较的时候是一个内存单元地比较,就是一个字节地比较
  • size_t num       比较num个字节/内存单元
  • int                     返回类型为int,满足的条件为:

(2).函数作用

  • 比较两个指针所指向的内存块里的内容,是一个字节地对比。
  • 和strcmp函数不同的是,memcmp不会因为检测到'\0'就结束比较。

(3).函数使用

(4).模拟实现

int my_memcmp(const void* ptr1, const void* ptr2, size_t num)
{
	while (*((char*)ptr1)==*((char*)ptr2))//相等就继续判断
	{
		if (num == 0)//如果num次都判断完了,那么就返回0
			return 0;
		num--;
		((char*)ptr1)++;
		((char*)ptr2)++;
	}
	return (int)(*(char*)ptr1 - *(char*)ptr2);//找到不相等的就返回差值

}


本章内容结束,下章见,拜拜!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值