c语言----内存操作函数(memcpy、memmove、memcmp、memset)

目录

前言:

一,内存初始化函数(memset)

1.函数说明

2.模拟实现 

3.代码运行下的内存空间图示

二,内存拷贝函数(memcpy)

1.函数说明

2.函数实现过程,以及跟strcpy的区别

3.模拟实现

三,memmove

1.函数说明

2.模拟实现

3.my_memcpy和my_memmove的区别:

四,比较函数memcmp 

1.函数说明


前言:

本文章会详解C语言中有关内存操作函数(memcpy,memmove,memcmp,memset)的使用说明。


一,内存初始化函数(memset)

1.函数说明

库函数memset函数声明:void*memset(void *dest,int c,size_t count)

dest:一块空间的起始地址。

c:对这块空间中每个字节要初始化的数据

count:从dest起始地址开始,要设置多少个字节的空间

返回值:返回dest空间地址。

2.模拟实现 

#include
#include
void *my_memset(void *dest, int c, size_t count)
{
	for (int i = 0; i < count; i++)
	{
		*(((char*)dest) + i) = c;
	}
	return dest;
}

int main()
{
	char str[] = "Hello world";
	my_memset(str, 0, sizeof(str));
	return 0;
}

3.代码运行下的内存空间图示

c语言----内存操作函数(memcpy、memmove、memcmp、memset)_第1张图片

 红色部分为为原始的str内存空间的值

运行经过my_memset(str, 0, sizeof(str));

 c语言----内存操作函数(memcpy、memmove、memcmp、memset)_第2张图片

 这时内存空间内的值全部被初始化为了0.


二,内存拷贝函数(memcpy)

1.函数说明

库函数memcpy函数声明:void *memcpy(void*dest,const void* src,size_t count);

 dest:目标空间

src:源数据空间

count:大小

功能:从src指向的空间中拷贝count字节的数据到dest空间中。

返回值:返回dest空间首地址

2.函数实现过程,以及跟strcpy的区别

int main()
{
	char str[] = "Hello world\0 fdsf  dfsa"; 
	char buf[1024] = { 0 };
	strcpy(buf, str);
	memset(buf, 0, 1024);
	memcpy(buf, str, sizeof(str));
	return 0;
}

我们特意在str这个字符串中加入了'\0'。用来观察strcpy和mencp的区别

 (1)开始时buf的内存空间全都是0

c语言----内存操作函数(memcpy、memmove、memcmp、memset)_第3张图片

 (2)经过strcpy拷贝赋值后的内存空间

c语言----内存操作函数(memcpy、memmove、memcmp、memset)_第4张图片

 因为str中有’\0‘,strcpy拷贝时,如果遇到’\0‘就会终止,所以等于只拷贝了Hello world。

(3)经过memcpy拷贝赋值后的内存空间

c语言----内存操作函数(memcpy、memmove、memcmp、memset)_第5张图片

 memcpy不会去管’\0‘,它会一直往后去拷贝,一直把需要的数据拷贝完。

3.模拟实现

void *my_memcpy(void *dest, const void *src, size_t count)
{
	assert(dest != NULL&&src != NULL);
	char*d = (char*)dest;
	char*s = (char*)src;
	while (count--)
	{
		*d++ = *s++;
	}
	return dest;
}

三,memmove

1.函数说明

库函数memmove函数声明:void * memmove ( void * destination, const void * source, size_t num );

 memmove和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
 如果源空间和目标空间出现重叠,就得使用memmove函数处理。

2.模拟实现

void *my_memmove(void *dest, const void *src, size_t count)
{
	assert(dest != NULL&&src != NULL);
	char*d = (char*)dest;
	char*s = (char*)src;
	if (s >= d || d >= s + count)
	{
		//不考虑内存重叠
		while (count--)
		{
			*d++ = *s++;
		}

	}
	else
	{
		//发生内存重叠,进行反向拷贝
		d= d + (count - 1);
		s = s + (count - 1);
		while (count--)
		{
			*d-- = *s--;
		}
		
	}
	return dest;
}

int main()
{
	char str[20] = "abcdefgh";
	my_memmove(str + 2, str, 4);
	printf("%s\n", str);

}

3.my_memcpy和my_memmove的区别:

 主要就是区别就在存在内存重叠时的处理。

(1)对于my_memcpy

int main()
{
    char str[20] = "abcdefgh";
    my_memcpy(str + 2, str, 4);

}

在进行这个操作时,原本我们想得到的输出是:ababcdgh. 但是结果如下:

 ​​​​​​c语言----内存操作函数(memcpy、memmove、memcmp、memset)_第6张图片

 原因:由于在进行拷贝时,出现了内存重叠,本来应该拷贝的c被已经拷贝过来的a值所覆盖,导致又让a被拷贝了一遍。

(2)对于my_memmove

int main()
{
	char str[20] = "abcdefgh";
	
	my_memmove(str + 2, str, 4);
}

c语言----内存操作函数(memcpy、memmove、memcmp、memset)_第7张图片

 my_memmove在实现时,考虑到了内存重叠的情况,加入了一个判断语句,当出现内存重叠时,使用反向的拷贝方法,避免了这一问题的出现。


四,比较函数memcmp 

1.函数说明

库函数memcmp函数声明:int memcmp ( const void * ptr1,const void * ptr2,size_t num );

memcmp与strcmp函数功能相似,只不过是可以对所有类型都进行一个字节一个字节的比较,逐字节比较内存的大小.

返回值情况:

‘< 0’ :"参数ptr1"与"参数ptr2"逐字节比较,"参数ptr1"数据 < “参数ptr2”;(VS编译器下返回值为 -1)
‘= 0’: "参数ptr1"与"参数ptr2"内存大小相等;(VS编译器下返回值为 0)
‘> 0’:"参数ptr1"与"参数ptr2"逐字节比较,"参数ptr1"数据 > “参数ptr2”。(VS编译器下返回值为 1)

 

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