C语言内存函数

memory

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

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

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

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

1.memcpy函数

(1).函数定义

cpp 复制代码
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).模拟实现

cpp 复制代码
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).函数定义

cpp 复制代码
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).模拟实现

分析:

cpp 复制代码
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).函数定义

cpp 复制代码
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).模拟实现

cpp 复制代码
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).函数定义

cpp 复制代码
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).模拟实现

cpp 复制代码
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);//找到不相等的就返回差值

}

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

相关推荐
许野平16 分钟前
Rust: 利用 chrono 库实现日期和字符串互相转换
开发语言·后端·rust·字符串·转换·日期·chrono
也无晴也无风雨19 分钟前
在JS中, 0 == [0] 吗
开发语言·javascript
狂奔solar27 分钟前
yelp数据集上识别潜在的热门商家
开发语言·python
朱一头zcy1 小时前
C语言复习第9章 字符串/字符/内存函数
c语言
此生只爱蛋1 小时前
【手撕排序2】快速排序
c语言·c++·算法·排序算法
blammmp1 小时前
Java:数据结构-枚举
java·开发语言·数据结构
何曾参静谧1 小时前
「C/C++」C/C++ 指针篇 之 指针运算
c语言·开发语言·c++
暗黑起源喵1 小时前
设计模式-工厂设计模式
java·开发语言·设计模式
WaaTong1 小时前
Java反射
java·开发语言·反射
Troc_wangpeng1 小时前
R language 关于二维平面直角坐标系的制作
开发语言·机器学习