零基础小白学习 c语言基础篇---------------内存操作函数

一.memcpy函数(内存拷贝)

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

解释:destination 目标空间(要拷贝的地点)source(起始空间)size_t num(要拷贝多少个字节)  同时为什么source这需要加const修饰,因为我们原空间内的数据是不变的,只是目标空间发生变化,让source受到保护。

1.memcpy库函数的使用:

举个例子:(图)

是指要从arr1中拷贝20个字节给arr2,也就是前5个整型(int 4B),这是我们使用库里的函数实现的,所以我们要引用头文件#include<string.h>。

2.模拟实现memcpy函数:(大家看一下注释,一步步非常详细)
#include<string.h>
#include <assert.h>
void* my_memcpy(void* dest,const  void* src, size_t sz)//会改变目标空间,但不会改变src所以加个const修饰,让src受到保护,*src限制src改变
{
	                     // void *指针是不能直接进行解引用加减操作的,要转化呀
    char* ret = dest;//返回目标空间
	assert(dest && src);//两个都不能为NULL
	while (sz--)//字节数,拷贝完1个--
	{
		*(char*)dest = *(char*)src;//强转然后解引用 为什么是char 类型,因为不管想要拷贝几个字节都可以 如果整形正能拷贝偶数项那么奇数项就不行了,char拷贝几个都行
		//所以一次拷贝1个字节拷贝sz次 sz--
		dest = (char*)dest + 1;//为什么这右再次++,因为强制类型转换是临时的,所以再++之时还需要再转换
		src = (char*)src + 1;//那能 (char*)dest++;不能在不同的编译器会出现错误,因为++的优先级更高,所以先++再强制转换,在强制转换前就已经改变了数
	}
    return ret;
}
int main()
{
	int arr1[10] = { 0 };
	int arr2[] = { 1,2,3,4,5 };
	my_memcpy(arr1, arr2, 20);//要拷贝20个字节 把arr2中的前五个整型,拷贝到arr1中,
	return 0;
}

二.memmove函数(内存拷贝)

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

那其实与memcpy都是内存拷贝,那有什么区别呢?

那之前我们是在两个数组中进行,而在一个数组进行内存重叠拷贝可以吗?让我们试一下。

1.memmove库函数的使用

解释:大致意思是要把3 4 5 6 7 拷贝到1 2 3 4 5 上进行内存的重叠拷贝

           arr+2指向3    要拷贝20个字节     拷贝到目标空间arr 指向1的位置

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(arr, arr + 2, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}
2.模拟实现memmove函数

(1)首先我们先要分析一下从前往后比还是从后往前比较呢

         地址是由低到高的,当地址dest<src时3拷贝到1,4-2 ,5-3,6-4,7-5,这样可以的它不至于把数据给挡了。当src<dest时由后到前。当在7之后,两者都可以。

#include<assert.h>
void* my_memmove(void* dest, const void* src, size_t sz)
{
	char* ret = dest;
	assert(dest && src);
	前-后
	if (dest < src)//地址的大小 由低到高  dest再src的左边  前到后 
	{
		int i = 0;
		for (i = 0; i < sz; i++)
		{
			*(char*)dest = *(char*)src;
			dest=(char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else                                  
	{                                          //后到前
		while (sz--)//--之后sz为19
		{
			*((char*)dest+sz) = *((char*)src+sz);
		}
	}
	return ret;
}
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr, arr + 2, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

问题思考?

在上面我们知道了memcpy和memmove都是内存拷贝,有什么样的区别呢?

int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	
	
	/*my_memcpy(arr1+2, arr1, 20);*///会实现吗 最后发现时1 2 1 2 1 2根本不是想要的,因为memcpy 
                                     //是实现不重叠的内存实现拷贝
	                                 //而memmove是实现重叠的内存拷贝
	/*my_memmove(arr1 + 2, arr1, 20);*///是可以的 12123458910
	//                                 那对于刚才我们自己写的函数不行,那真的是我们写的不行 
                                    // 吗?并不是,memcpy是拷贝未重叠部分,而使用库函数是可以的
	memcpy(arr1 + 2, arr1, 20);//是可以的,当使用库函数时memcpy可以拷贝重叠部分
	

	return 0;
} 

三.memset(设置内存函数,以字节为单位设置内存)

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

    是指:ptr所指向的前num个字节的值设置specific(具体 特殊的)为value

#include<string.h>
int main()
{
	/*char arr[] = "hello bit";
	memset(arr + 6, 'w', 3);*/

	int arr[10] = { 0 };
	memset(arr , 1,10);//这里调试 内存 成为 了  01 01 01 01因为它是以字节为单位并不是整型,并不是10个1
	printf("%s\n", arr);
	return 0;
}

四.memcmp函数(比较两个内存块,以字节来比较内存比较,无论什么类型都是内存中的数来比)

原型:int memcmp ( const void * ptr1, const void * ptr2, size_t num );
#include<string.h>
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7 };//内存中这样存的 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00
	//int arr2[] = { 1,2,3 }; //01 00 00 00 02 00 00 00 03 00 00 00相比较相等0
    int arr2[] = { 1,2,3 ,0x11223344 };//小端存储
	                                  // 内存中 01 00 00 00 02 00 00 00 03 00 00 00 44 33 22 11 
	int ret=memcmp(arr1, arr2, 13);//第13个字节也就是从03 和44比较 <所以为负数,不要眼见比较,要在内存内
	printf("%d\n", ret);
	return 0;
}

       文章最后: 如有知识点错误恳请小伙伴们指出,希望大家可以动动发财的小手手帮阿莹一键三连,阿莹万分感激!

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值