C语言内存函数memcpy、memmove、 memset、memcmp

C语言内存函数memcpy、memmove、 memset、memcmp_第1张图片

 ---------------------------------------------

夜色难免黑凉,前行必有曙光。

-------------今天我将带大家认识C语言中的内存函数

---------的使用和模拟实现

-----这些函数的头文件依然被#include所包含

目录

memcpy函数的使用

memcpy函数的模拟实现

memmove函数的使用 

memmove函数的模拟实现 

 memset函数的使用

 memcmp函数的使用


memcpy函数的使用

C语言内存函数memcpy、memmove、 memset、memcmp_第2张图片

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

1.函数memcpy是从cource的位置开始向后复制num字节数据到destination指向的内存位置

2.函数memcpy在遇到'\0'并不会停下来依然可以拷贝'\0'后面位置

3. source和destination不能有重叠

4.常被我们用来拷贝非字符串的类型

 以下是memcpy函数的一般用法:

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
int main()
{
	int arr[] = { 1,3,5,7,9,2,4,6,8,0 };
	int str[10] = { 0 };
	memcpy(str,arr , 20);
//内存函数的单位是字节,20字节就是5个整形元素
//也可以这么写memcpy(str,arr,5*sizeof(int))
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", str[i]);
	}
	return 0;
}

C语言内存函数memcpy、memmove、 memset、memcmp_第3张图片

我们来验证一下,memcpy遇到'\0'是否不会停止: 

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
int main()
{
	char arr[] = "Hel\0lo World!";
	char str[10] = { 0 };
	memcpy(str, arr, 6 * sizeof(char));
	for (int i = 0; i < 6; i++)
	{
		printf("%c", str[i]);
	}
	return 0;
}

C语言内存函数memcpy、memmove、 memset、memcmp_第4张图片

我们可以看到memcpy函数并不会因为遇到'\0'而停止,它会把'\0' 拷贝到目标函数

memcpy函数的模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
void* my_memcpy(void* arr, const void* str, size_t num)
         //因为这个函数可以运用到多种类型,所以用了void*(无具体类型的指针)
{
	void* ret = arr;
	while (num--)
	{
		*(char*)arr = *(char*)str;
		arr = (char*)arr+1;   
		str = (char*)str + 1;
//强制类型转换为char类型可以一个字节一个字节的访问
	}
	return ret;
//返回目标函数的起始地址
}
int main()
{
	char arr[] = { 1,3,5,7,9,2,4,6,8,0 };
	char str[10] = { 0 };
	my_memcpy(str, arr, 5 * sizeof(int));
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", str[i]);
	}
	return 0;
}

 memcpy中重叠拷贝问题:

C语言内存函数memcpy、memmove、 memset、memcmp_第5张图片

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
void* my_memcpy(void* arr, const void* str, size_t num)
{
	void* ret = arr;
	while (num--)
	{
		*(char*)arr = *(char*)str;
		arr = (char*)arr + 1;
		str = (char*)str + 1;
	}
return ret;
}
int main()
{
	int arr[10] = { 1,3,5,7,9,2,4,6,8,0 };
	my_memcpy(arr+3, arr, 5 * sizeof(int));
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

C语言内存函数memcpy、memmove、 memset、memcmp_第6张图片

VS2022的库函数里面的memcpy可以重叠拷贝,但有些编译器不行

为了表示区分,我们以后重叠拷贝都不用memcpy

可以用memmove函数来实现重叠拷贝

memmove函数的使用 

C语言内存函数memcpy、memmove、 memset、memcmp_第7张图片

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

 1.memmove和memcpy的区别就是源内空间可以和目标空间重叠

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
int main()
{
	int arr[10] = { 1,3,5,7,9,2,4,6,8,0 };
	memmove(arr+3, arr, 5 * sizeof(int));
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

C语言内存函数memcpy、memmove、 memset、memcmp_第8张图片

我们可以发现memmove把我们刚刚源内空间和目标空间重叠的问题很好的解决了

接下来让我们看看它是怎么实现的吧

memmove函数的模拟实现 

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
void* my_memmove(void* dst, const void* src, size_t count)
{
	void* ret = dst;
	if (dst <= src || (char*)dst >= ((char*)src + count)) {
		while (count--) {
                  //从前向后拷贝
			*(char*)dst = *(char*)src;
			dst = (char*)dst + 1;
			src = (char*)src + 1;
		}
	}
	else {
                  //从后向前拷贝
		dst = (char*)dst + count - 1;
		src = (char*)src + count - 1;
		while (count--) {
			*(char*)dst = *(char*)src;
			dst = (char*)dst - 1;
			src = (char*)src - 1;
		}
	}
	return ret;
}
int main()
{
	int arr[10] = { 1,3,5,7,9,2,4,6,8,0 };
	my_memmove(arr + 3, arr, 5 * sizeof(int));
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

C语言内存函数memcpy、memmove、 memset、memcmp_第9张图片

接下来我将会以画图的形式帮助大家理解:

C语言内存函数memcpy、memmove、 memset、memcmp_第10张图片

C语言内存函数memcpy、memmove、 memset、memcmp_第11张图片

C语言内存函数memcpy、memmove、 memset、memcmp_第12张图片

C语言内存函数memcpy、memmove、 memset、memcmp_第13张图片

 memset函数的使用

C语言内存函数memcpy、memmove、 memset、memcmp_第14张图片

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

1.memsrt常被我们用来设置内存,将内存中的值以字节为单位设置成想要的内容 

#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include 
int main()
{
	char arr[] = "hello world";
	memset(arr, 'x', 6);
	printf(arr);
	return 0;
}

C语言内存函数memcpy、memmove、 memset、memcmp_第15张图片

 这样来看我们是不是把hello 的内容设置成"x"了!这就是memset函数的运用场景。

 memcmp函数的使用

C语言内存函数memcpy、memmove、 memset、memcmp_第16张图片

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

1.比较ptr1和ptr2指针指向的位置开始,向后的num个字节 

#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include 
int main()
{
	char arr[] = "abcdfe";
	char str[] = "abcdefg";
	int n;
	n = memcmp(arr, str, sizeof(arr));
	if (n > 0)
		printf("'%s' 大于 '%s'.\n",arr ,str );
	else if (n < 0)
		printf("'%s' 小于 '%s'.\n", arr,str );
	else
		printf("'%s' 等于 '%s'.\n",arr ,str );
	return 0;
}

C语言内存函数memcpy、memmove、 memset、memcmp_第17张图片

 今天的介绍就到这里啦!

C语言内存函数memcpy、memmove、 memset、memcmp_第18张图片

后续我将会把结构体方面的知识点整理出来

希望大家长期关注 !

感谢支持

你可能感兴趣的:(c语言,开发语言)