C/C++内存函数的用法及其实现( 超详细)

个人主页:

仍有未知等待探索_C语言疑难,数据结构,PTA-CSDN博客

专题分栏:

C语言疑难_仍有未知等待探索的博客-CSDN博客

目录

一、引言

二、memcpy——内存拷贝函数

1、参数

2、用法 

3、函数的具体的作用

4、具体实现 

 三、memmove——内存移动函数(实现有重叠的拷贝)

 1、参数

2、用法 

3、函数的具体的作用

4、具体实现 

四、memcmp——内存比较函数 

1、用法


一、引言

估计大家都很疑惑,内存函数是什么东西啊。memcpy——用来实现数据拷贝的函数,都已经有strcpy了,为什么又要写一个内存拷贝函数啊。

在内存中,我们要知道不仅仅是有字符串,还有整型,浮点型等等。这些其他的类型不能用字符串拷贝函数进行拷贝,而需要我们要讲的内存拷贝函数。

内存函数—— string.h(头文件) 
内存拷贝函数 memcpy
内存移动函数(实现有重叠的拷贝) memmove
内存比较函数 memcmp

二、memcpy——内存拷贝函数

1、参数

destination:指向要在其中复制内容的目标数组的指针,类型转换为 void* 类型的指针。

source:指向要复制的数据源的指针,类型转换为 const void* 类型的指针。

num:要复制的字节数。(size_t是指无符号数

2、用法 

1.函数的作用是:将source所指向的内容往后复制num个字节到destination的位置上。

2.这个函数遇到'\0'不会停止

3.这个函数遇到重叠的时候会怎么复制不确定。(有的编译器会考虑,有的编译器就不考虑)

3、函数的具体的作用

#include<stdio.h>
#include<string.h>
int main()
{
	int a[5] = {1,2,3,4,5};
	int b[10];
	memcpy(b, a,sizeof(a));//仅复制了a数组,b剩余未复制的为随机值
	for (int i = 0; i < sizeof(b) / sizeof(b[0]); i++)
		printf("%d\n", b[i]);
	return 0;
}

4、具体实现 

从上面库函数的声明中看见函数参数的类型是void*类型和size_t类型。

我们需要知道void*类型的指针不能直接进行解引用操作和运算操作,需要把它进行强制类型转化为所适合的类型,然后再进行相应的操作。

而对于内存中的数据,我们在写函数的时候并不知道程序员将调用这个函数来完成什么类型的数据拷贝,如果将它强转成(int*)类型的话,在需要复制的数据所占空间不是4的整数的时候在边界会一些问题。

所以我们就干脆强转成(char*)类型,来一个字节一个字节进行拷贝。

指针往后走一位的时候,记得不能直接在destination后面+1或者++操作,不合法。

#include<stdio.h>
#include<string.h>
void my_memcpy(void* destination, void* source, size_t num);
int main()
{
	int a[5] = {1,2,3,4,5};
	int b[10];
	my_memcpy(b, a,sizeof(a));
	for (int i = 0; i < sizeof(b) / sizeof(b[0]); i++)
		printf("%d\n", b[i]);
	return 0;
}
void my_memcpy(void* destination, void* source, size_t num)
{
	while (num--)
	{
		*(char*)destination = *(char*)source;
		destination = (char*)destination + 1;
		source = (char*)source + 1;
	}
}

 三、memmove——内存移动函数(实现有重叠的拷贝)

 1、参数

destination:指向要在其中复制内容的目标数组的指针,类型转换为 void* 类型的指针。

source:指向要复制的数据源的指针,类型转换为 const void* 类型的指针。

num:要复制的字节数。(size_t是指无符号数

2、用法 

1。memcpy和memmove的区别:memmove适用于区域重叠的来进行拷贝。

3、函数的具体的作用

#include <stdio.h>
#include <string.h>
int main()
{
	char str[] = "memmove can be very useful......";
	memmove(str + 20, str + 15, 11);
	puts(str);
	return 0;
}

4、具体实现 

这个和内存拷贝函数有异曲同工之处,唯一的不同就是需要判断是从前往后复制还是从后往前复制。如果不是下面的顺序的话,会造成覆盖,可以自行检验。

#define _CRT_SECURE_NO_WARNINGS  1
#include<stdio.h>
#include<string.h>
void my_memmove(void* dest, void* ser, size_t sz);
int main()
{
	int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(a, a+2 , sizeof(a[0])*5);
	printf("my_memmove:\t");
	for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
		printf("%d ", a[i]);
	printf("\n");
	printf("memmove:\t");
	int b[10] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(b, b+2, sizeof(b[0]) * 5);
	for (int i = 0; i < sizeof(b) / sizeof(b[0]); i++)
		printf("%d ", b[i]);
	return 0;
}
void my_memmove(void* dest, void* ser, size_t sz)
{
	if (dest < ser)
	{
		//从头往后
		while (sz--)
		{
			*(char*)dest = *(char*)ser;
			dest = (char*)dest + 1;
			ser = (char*)ser + 1;
		}
	}
	else if (dest > ser)
	{
		//从后往前
		while (sz--)
		{
			*((char*)dest+sz) = *((char*)ser+sz);
		}
	}
	else
	{
		return;
	}
}

四、memcmp——内存比较函数 

这个内存比较函数和strcmp一样,没有什么新奇的,唯一的不同就是多一个参数num,用来决定判断的个数。

1、用法

注: 最后一个数据不一样不一定代表memcmp的返回值为0

#include<stdio.h>
#include<string.h>
int main()
{
	int a[] = { 1,2,3,4,5,6,7 };
	int b[] = { 1,2,3,0x11223304 };
	printf("%d", memcmp(a, b, 13));
	return 0;
}

谢谢大家的支持!

猜你喜欢

转载自blog.csdn.net/qq_73435980/article/details/133582607