C语言内存函数

目录

1.memcpy的使用和模拟实现

memcpy的使用

memcpy的模拟实现

2.memmove的使用和模拟实现

memmove的使用

memmove的模拟实现

3.memset函数的使用

4.memcmp的使用


1.memcpy的使用和模拟实现

void * memcpy(void * destinantion, const void * source, size_t num);
  •  strncpy—字符串的拷贝  memcpy—针对内存块进行拷贝
  • 函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。
  • 这个函数在遇到'\0'时不会停下来。
  • 如果source和destination有任何的重叠,复制的结果都是未定义的。

memcpy的使用

#include<stdio.h>
#include<string.h>

int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = { 0 };
	memcpy(arr2, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}
  • 对于重叠的内存则交给memmove函数处理。

memcpy的模拟实现

#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* src, size_t num)
//在不确定函数类型的时候用void*指针
{
	assert(dest && src);//确保传入不为空指针
	void* ret = dest;//保存目标空间的起始地址
	while (num--)//确定循环的次数
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1; //((char*)dest)++;
		src = (char*)src + 1; //((char*)src)++;
	}
	//为什么不强制类型转换为int*类型的指针?
	//原因是char*类型的指针实用型更高,若传入的num值为7个字节
	//而一个整型指针跳过四个字节,无法使用整型指针来拷贝

	return ret;//memcpy拷贝完后会返回目标空间的起始地址
}

2.memmove的使用和模拟实现

void * memmove (void * destinantion, const void * source, size_t num)
  • 这里的num也指的是字节。 
  • 和memcpy的区别在于:memmove函数处理的源内存块和目标内存块是可以重叠的。
  • 如果源空间和目标空间出现重叠,接得使用memmove函数处理。

memmove的使用

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

输出的结果为:
 

1 2 1 2 3 4 5 8 9 10

memmove的模拟实现

  • 当src指针指向dest指针左侧时,如果按照从前向后的顺序进行拷贝,则会导致已经拷贝完成的数据会对后续的拷贝产生影响,那此时我们需要从后向前进行拷贝。
  • 同理当src指针指向dest指针右侧的时候,从后向前也会导致拷贝数据出错,将采取从前向后拷贝的方式。

那我们来模拟实现一下吧。

#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest, const void* src, size_t num)
{
	assert(dest && src);//断言防止传入空指针
	void* ret = dest;//保存目标空间的起始地址
	if (dest < src)//分情况讨论dest和src的位置
	{
		//从前向后拷贝
		//拷贝同memcpy
		while (num--)
		{
			*(char*)dest = *(char*)src;
			((char*)dest)++;
			((char*)src)++;
		}
	}
	else
	{
		//从后向前拷贝
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
			//假设num为20,进入循环num--,num的值变为19
			//char*类型的指针+19正好指向最后一个字节
			//对其解引用实现从最后一个字节开始向前拷贝
		}
	}
	return ret;
}

输出结果和上面是一样滴~

3.memset函数的使用

void * memset (void * ptr, int value, size_t num);
  • memset是用来设置内存的,将内存中的值以字节为单位设置成想要的内容。
  • 设置时是以字节为单位设置的。
#include<stdio.h>
#include<string.h>
int main()
{
	char str[] = "hello world";
	memset(str, 'x', 5);
	printf("%s", str);
	return 0;
}

输出的结果:

xxxxx world 

  • 整型(除0外)做不到以元素为单位设置。

4.memcmp的使用

int memcmp (const void * ptr1, const void * ptr2, size_t num);
  • 比较从ptr1和ptr2指针指向的位置开始,向后的num个字节。
  • 也是以字节为单位进行比较的。
  • num指的是最多比较次数。
  • 相较于strncmp的区别:该函数可以比较任意类型的数据。

函数的返回值如下:

#include<stdio.h>
#include<string.h>
int main()
{
	char buffer1[] = "abcddefg";
	char buffer2[] = "abcDeefg";
	int n = memcmp(buffer1, buffer2, sizeof(buffer1));
	if (n > 0)
		printf("buffer1 > buffer2");
	else if (n < 0)
		printf("buffer1 < buffer2");
	else
		printf("buffer1 = buffer2");
	return 0;
}

输出的结果:

buffer1 > buffer2

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值