内存操作函数---模拟实现memcpy函数和memmove函数

目录

前言:

1.memcpy函数

2.memmove函数

3.memcmp函数

4.memset函数


前言:

我们向大家介绍四个内存函数---memcpy,memmove, memcmp,memset。其中包含模拟实现memcpy,memmove。

1.memcpy函数

//内存拷贝
void * memcpy ( void * destination, const void * source, size_t num );

memcpy函数从source位置开始向后复制num个字节的数据到destination的内存位置。它不会在遇到‘\0’的时候停下来。

特别注意:num表示字节个数,而不是元素个数。

举例:

注:void*可以接受任何类型的指针。

下面,我们来模拟实现memcpy函数:

void* my_memcpy(void* dest, const void* src, size_t num) {
	void* ret = dest;
	assert(dest);
	assert(src);
	while (num--) {
		*(char*)dest= *(char*)src;
		dest=(char*)dest + 1;
		src=(char*)src + 1;
	}
	return ret;
}
int main() {
	int arr1[] = { 1,8,2,3 };
	int arr2[10] = { 0 };
	//memcpy(arr2, arr1, 16);
	my_memcpy(arr2, arr1, 16);//1 8 2 3
	return 0;

2.memmove函数

//内存移动
void * memmove ( void * destination, const void * source, size_t num );

将num字节的值从源指向的位置复制到目标指向的内存块。遇到\0不会停止直到复制了num个字节。为了避免溢出,目标和源参数所指向的数组的大小至少应该是num字节。

注:c语言中重叠内存的拷贝是交给memove来实现的。

举例:

通过调试,我们也证实了通过memmove进行复制时,遇到\0后不会结束也不会往后一直复制\0,后续字符是什么就复制什么。

如果要实现重叠内存的拷贝呢???

举例1:

    int arr[23] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
	memmove(arr + 1, arr+4, 20);

通过调试,结果如下:

 

如何实现:

然而我们发现,不是所有情况都能够从前往后拷贝的,比如

举例2:

memmove(arr + 6, arr+4, 20);

结果:

 

实现过程:

这种情况有需要从后往前拷贝了。

举例3:

总结:如果dest落在src前,我们从前往后拷贝,如果dest落在src后,我们则从后往前拷贝。

下面,我们来模拟实现memmove函数:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
void* my_memmove(void* dest, const void* src, size_t num) {
	void* ret = dest;
//dest落在src前
	if (dest < src) {
		while (num--) {
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
//dest落在src后和刚好落在src位置上
	else {
		while(num--){
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	return ret;
}
int main() {
	int arr[23] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
	//memmove(arr + 1, arr+4, 20);
	my_memmove(arr + 1, arr + 4, 20);
	for (int i = 0; i < 23; i++) {
		printf("%d ", arr[i]);
	}//1 5 6 7 8 9 7 8 9 10 11 12 0 0 0...
return 0;
}

3.memcmp函数

//内存比较
int memcmp ( const void * ptr1, const void * ptr2, size_t num );

 将ptr1指向的内存块的第一个num字节与ptr2指向的第一个num字节进行比较,如果它们都匹配则返回0,如果不匹配则返回一个不同于0的值,表示哪个值更大。

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,8,5};//01 00 00 00 02 00 00 00 03 00 00 00 08 00 00 00 05 00 00 00
int ret=memcmp(arr1,arr2,13);//<0
printf("%d",ret);//<0的一个数字

4.memset函数

//内存设置
void * memset ( void * ptr, int value, size_t num );

将某一块指定内存中的全部设置为指定的值 ,即将前num个字节的全部内容设置为value。

    int arr1[] = { 1,2,3,4,5 };//01 00 00 00 02 00 00 00...
	int arr2[] = { 1,2,3,8,5 };
	for (int i = 0; i < 5; i++) {
		printf("%d ", arr1[i]);//03 03 03 03 03 00 00 00...
	}//50529027 3 3 4 5

好啦,以上就是今天我们要介绍的几个内存函数,祝大家健健康康顺顺利利,下次见!!!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值