C语言内存函数

C语言内存函数

它是针对内存块来处理的,内存块就是一块内存

mem - 记忆、内存的意思 
memcpy - 内存拷贝
memmove - 内存移动
memset - 内存设置
memcmp - 内存比较
这些函数使用时都需要包含对应的头文件  string.h

memcpy

该函数属于泛型函数,他可以拷贝整型数据、浮点型数据、结构体数据等等。因此它的类型是void *
表达式如下:

void * memcpy ( void * destination, const void * source, size_t num );

destination:目标空间的地址
source: 源空间的地址
num :被拷贝的字节个数
它返回的是目标空间的起始地址
memcpy函数从源头开始的位置复制num个字节的数据到目标空间所在内存的位置
需要注意的:
目标空间的内存足够大
memcpy遇到’\0’ 不会停止,该拷贝多少个字节就拷贝多少
memcpy只负责不重叠的拷贝,不负责重叠的拷贝,如果非要使用,它的结果是未定义的

memcpy的使用及模拟实现

思维逻辑图:
在这里插入图片描述

//memcpy的使用
#include<string.h>
int main()
{
	int arr1[] = { 1,3,5,7,9,2,4,6,8,10 };
					    //arr1 + 3 :7的地址
	int arr2[20] = { 0 };
	//将arr1中的7,9,2,4,6拷贝到arr2中 4*5 = 20个字节
	memcpy(arr2, arr1 + 3, 20);
	int i = 0;
	for (i = 0; i < 20; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

//模拟实现memcpy
#include<assert.h>
					//不可修改加上const
void* my_memcpy(void* dest, const void* src, size_t num)
{
	//(int*)dest = (int*)src;//如果强转为int*,权限不够细分,假设我想要17个字节呢
	assert(dest && src);
	
	void* ret = dest;//它的返回值是目标空间的起始地址,这里是为了防止后面dest++导致dest的起始地址发生改变
	int i = 0;
	for (i = 0; i < num; i++)
	{
		*(char*)dest = *(char*)src;//因为void* 不能够直接进行运算,需要强转
		//dest++; //void* 不能够直接进行运算
		//src++;
		//(char*)dest++;
		//(char*)src++;//因为强转是临时的,当我++后去使用它时他已经不是强转后的了
		
		//++(char*)dest;//不能保证所有编译器都能够通过
		//++(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	//while (num--)//也可以使用while来实现
	//{
	//	*(char*)dest = *(char*)src;

	//	dest = (char*)dest + 1;
	//	src = (char*)src + 1;

	//}
	return ret;
}
int main()
{
	int arr1[] = { 1,3,5,7,9,2,4,6,8,10 };
					    //arr1 + 3 :7的地址
	int arr2[20] = { 0 };
	//将arr1中的7,9,2,4,6拷贝到arr2中 4*5 = 20个字节
	my_memcpy(arr2, arr1 + 3, 20);
	int i = 0;
	for (i = 0; i < 20; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

memmove

表达式如下:

void * memmove ( void * destination, const void * source, size_t num );

memmove函数来处理重叠的内存
memmove 的使用及模拟实现
思维逻辑图:
在这里插入图片描述

#include<string.h>
int main()
{
	int arr1[] = { 1,3,5,7,9,2,4,6,8,10 };
	//arr1 + 3 :7的地址
	memmove(arr1 +2, arr1, 20);

 	return 0;
}

//memmove 模拟实现 --- 要将图画的过程自己思考并且画出来

#include<assert.h>
void* my_memmove(void* dest, void* src, size_t num)
{
	assert(dest && src);
	void* ret = dest;
	if (dest < src)//从前往后
	{ 
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else//从后往前
	{
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);//转换为char*的地址后加上减减后的num,以此达到从后向前的结果
		}
	}
}
int main()
{
	int arr1[] = { 1,3,5,7,9,2,4,6,8,10 };
	my_memmove(arr1 + 2, arr1, 20);//从前往后都可以试试
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
 	return 0;
}

C语言标准规定memcpy只要能实现不重叠的拷贝就行
重叠的交给memmove

在VS上可能能够实现,但不能够保证在其他编译器上能够正常运行

//memcpy 只负责重叠的就行,Vs是个特例
#include<string.h>

int main()
{
	int arr1[] = { 1,3,5,7,9,2,4,6,8,10 };
	memcpy(arr1 + 2, arr1, 20);//从前往后都可以试试
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
 	return 0;
}

memset 内存设置

memset函数 是用来设置内存的,将内存中的值以字节为单位设置成想要的内容
表达式如下:

void * memset ( void * ptr, int value, size_t num );

ptr: 你想要设置内存所指向的指针(地址)。
value:这里是你想要设置成怎样的值。
num:设置成值的字节数
memset的使用

#include<string.h>
int main()
{
	char arr[] = "hello world";
	memset(arr + 6, 'G', 5);//要记得加上 ''
	printf("%s\n", arr);
	return 0;
}
#include<string.h>
int main()
{
	int arr[10] = { 0 };
	memset(arr, 1, 4);//通过F10 + 内存 我们可以知道 memset 是以字节数为单位进行设置的,而不是以元素为单位进行设置的
	return 0;
}

memcmp函数 - 内存比较

比较ptr1 和 ptr2 各自指向的地址开始向后num个字节的大小
表达式如下:

int memcmp ( const void * ptr1, const void * ptr2, size_t num );

ptr1 和ptr2 :两个要进行比较的内存大小的地址
num: 比较它俩各自大小的字节数
memcmp函数不仅仅可以比较字符串类型的,其他类型的也可以进行比较
memcmp 的使用

#include<string.h>
int main()
{
	char arr1[] = "i love you forever";
	char arr2[] = "i love you noforever";
	int ret1 = memcmp(arr1, arr2, 11);
	printf("%d\n", ret1);//0
	int ret2 = memcmp(arr1, arr2, 12);
	printf("%d\n", ret2);//-1
	return 0;
}

//整型类型的比较
#include<string.h>
int main()
{
	//0000 0000 00000000 00000000 00000001
	//0x00 00 00 01
	int arr1[] = { 1,2,3,4,5 };
	//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00
	int arr2[] = { 1,2,3,6,5 };
	//01 00 00 00 02 00 00 00 03 00 00 00 06 00 00 00 05 00 00 00
	//数据在内存中是以16进制倒着存放的
	int ret = memcmp(arr1, arr2, 13);

	printf("%d\n", ret);
	return 0;
}
memcmp函数如果:			     	       在VS上分别返回
ptr1 < ptr2   返回小于0的值  			-1
ptr1 = ptr2  返回0			  			 0
ptr1 > ptr2 返回大于0的值				 1
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值