字符串系列(三)--- 内存操作函数


前言

本文将详细介绍内存操作函数的使用及其实现方法

一、内存操作函数

1、memcpy --内存拷贝函数

首先看下C语言库函数中对于这个函数的定义,void *memcpy( void *dest, const void *src, size_t count );首先,就和字符串不同了,字符串的函数参数类型是char * ,而内存操作函数时void *,可操作的操作数更多。如果重叠则函数未定义。如何使用?看以下代码

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "hello bit";
	char arr2[] = "welcome";
	printf("%s", (char*)memcpy(arr1, arr2, 7));
	return 0;
}

在这里插入图片描述
在这里插入图片描述
(2)自己实现
实际上对于这个函数,库函数设计的是可以接收任意字符的,那再设计函数就不能说指针往后遍历一步是4个字节或者8个字节,而是统一设计成一个字节,一个字节一个字节的进行交换

#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest, void* src, int num)
{
	assert(dest && src);
	void* start = dest;
	char tmp = 0;
	while (num--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return start;
}
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 2,3,4,5,6 };
	int k = 0;
	scanf("%d", &k);
	int *p = (int*) my_memcpy(arr1, arr2, k);
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		printf("%d", *(p + i));
	}
	return 0;
}

2、memmove – 全能函数

首先看下C语言中对于memmove的定义,void *memmove( void *dest, const void *src, size_t count );
和memcpy是相同的,唯一不同的是,memmove可以处理重叠的区域移动和复制。

#include<string.h>
#include<stdio.h>
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[] = { 1,1,1,1,1 };
	int* p = memmove(arr1, arr1+2, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", *(p + i));
	}
	return 0;
}

在这里插入图片描述
(2)自己实现
这个函数是比较难的,首先dest指针和src指针指向的内存空间是不清楚的,就应该分类讨论。如果dest在src左边,看下图
在这里插入图片描述
如果src 和 dest 相同呢?那也是第一种方法。
但是如果src小于dest,就是目标地址在右边,源地址在左边,看下图
在这里插入图片描述
因为我如果还是按照上面的依次往后面复制,那么会把本来要拷贝的456覆盖了
代码如何实现呢?


#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest, void* src, int num)
{
	assert(dest && src);
	void* start = dest;
	char tmp = 0;
	if (dest <= src)
	{
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		for (int i = num - 1; i >= 0; i--)
		{
			*((char*)dest + i) = *((char*)src + i);
		}
	}
	return start;
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[] = { 1,1,1,1,1 };
	int k = 0;
	scanf("%d", &k);
	int* p = (int*)my_memmove(arr1 + 3, arr1, k);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", *(p - 3 + i));
	}
	return 0;
}

3、memcmp

首先来看下C语言库函数对于这个函数的定义
int memcmp( const void *buf1, const void *buf2, size_t count );
返回类型是int ,buf1和buf2是两个要比较的地址,count是要比较的字节数量,注意,所有的操作都是在内存中进行的比较。

#include<stdio.h>
#include<string.h>
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 1,2,3,5,6 };
	int k = 0;
	scanf("%d", &k);
	printf("%d", memcmp(arr1, arr2, k));
	return 0;
}

比方我比较前12个字节,也就是前三个整型,是一样的
在这里插入图片描述
前13个字节呢?在第13个字节是不是就不一样了,就是04小于05了,所以会输出-1
在这里插入图片描述
(2)自己实现
其实实现方法和strcmp是很像的,只是函数参数需要处理,看代码

#include<stdio.h>

int my_memcmp(const void* buf1, const void* buf2, int k)
{
	int signel = 0;
	while (k--)
	{
		if (*(char*)buf1 == *(char*)buf2)
		{
			if (*(char*)buf1 != *(char*)buf2)
			{
				signel = 1;
				break;
			}
			buf1 = (char*)buf1 + 1;
			buf2 = (char*)buf2 + 1;
		}
		else //如果第1个就不相同而的情况
		{
			signel = 1;
			break;
		}
	}
	if (signel == 0)
		return 0;
	else
	{
		if (*(char*)buf1 > *(char*)buf2)
			return 1;
		else
			return -1;
	}

}
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 1,2,3,5,6 };
	int k = 0;
	scanf("%d", &k);
	printf("%d", my_memcmp(arr1, arr2, k));
	return 0;
}

总结

字符串系列就正式完结了,如果喜欢,还请给博主点下关注和大大的赞。下一个系列是自定义类型讲解。

  • 27
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值