【C语言】memcpy memmove memset memcmp 四大内存操作函数(详解+用法+模拟实现)

这篇具有很好参考价值的文章主要介绍了【C语言】memcpy memmove memset memcmp 四大内存操作函数(详解+用法+模拟实现)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

头文件<string.h>中常用内存操作函数共有四大,学习完本篇文章,各种类型数组的常见处理轻松拿下。

零、前言

对字符串(字符数组)的操作函数有很多,但是我们想要操作整型数组等呢:
这就需要内存操作函数了,memory在计算机科学中是内存的意思,这也是四大内存操作函数都有mem头的原因。
与void*类型指针重要的知识:

void*类型指针可以指向任何类型的数据,但是void*类型指针无法访问地址数据。这是因为指针压根就不知道它要访问多大空间,那么即使能访问得到的数据也毫无意义。因此不能对void*类型指针解引用操作,也不能做地址偏移±操作,这是语法型错误。

本文提及的字符串相关函数不熟悉的可以查看文章【C语言】<string.h>中十大字符串函数(用法+模拟实现)。

一、memcpy 内存拷贝函数

我们知道strcpy(字符串拷贝函数)可以将一个字符串内容拷贝到另一个字符串,如果我们想拷贝整型数组,我们可以使用memcpy内存拷贝函数。
memcpy头文件:string.h
memcpy功能:逐字节地拷贝num个字节内存,并会覆盖原来内容。
memcpy函数声明:

void * memcpy ( void * dst, const void * src, size_t num );

src(source)源内存首字节地址,dst(destination)目标内存首字节地址。
num是需要拷贝的字节数。
memcpy返回的是dst首字节地址,并且是void*型,接收返回值需要强制类型转换。
memcpy使用实例:

#include <stdio.h>
#include <string.h>
int main()
{
	int arr1[10] = { 0 };
	int arr2[10] = { 1,2,3,4,5,6,7,8,9,10 };
	memcpy(arr1, arr2, 4 * sizeof(arr2[0]));
	for (int i = 0; i < 10; i++)
		printf("%d ", arr1[i]);
	printf("\n");
	memcpy(arr1+2,arr1,4*sizeof(arr1[0]));
	//理想拷贝后效果应该是1 2 1 2 3 4 0 0 0 0
	//实际输出是1 2 1 2 1 2 0 0 0 0 因为原来的3 4被提前覆盖了
	for (int i = 0; i < 10; i++)
		printf("%d ", arr1[i]);
	return 0;
}

注意:
dst和src都要有超过num个字节的空间。
源内存块src和目标内存块dst有任何的重叠,复制的结果都是未定义的。

memcmp函数,C语言库函数篇,c语言,c++,数据结构,算法

my_memcpy

void *my_memcpy(void *dst, const void *src, int num)
{
	//将void*型强制转化成char*,能够逐字节访问
	char *tmp_dst = (char *)dst;
	const char *tmp_src = (const char *)src;
	//循环num次,拷贝num个字节
	for (int i = 0; i < num; i++)
	{
		*tmp_dst++ = *tmp_src++;
	}
	return dst;
}

二、memmove 内存移动函数

memmove和memcpy的差别就是处理的源内存块和目标内存块是可以重叠的。
memmove头文件:string.h
memmove功能:将源内存块num个字节移动到目标内存块,源内存块内容并不消失。
memmove函数声明:

void * memmove ( void * dst, const void * src, size_t num );

src(source)源内存首字节地址,dst(destination)目标内存首字节地址。
num是需要拷贝的字节数。
memmove返回的是dst首字节地址,并且是void*型,接收返回值需要强制类型转换。
memmove使用实例:

#include <stdio.h>
#include <string.h>
int main()
{
	int arr1[10] = { 0 };
	int arr2[10] = { 1,2,3,4,5,6,7,8,9,10 };

	memmove(arr1, arr2, 4 * sizeof(arr2[0]));
	printf("arr1:");
	for (int i = 0; i < 10; i++)
		printf("%d ", arr1[i]);

	printf("\narr2:");
	for (int i = 0; i < 10; i++)
		printf("%d ", arr2[i]);

	//理想拷贝后效果应该是1 2 1 2 3 4 0 0 0 0
	printf("\narr1自己移动自己:");
	memmove(arr1 + 2, arr1, 4 * sizeof(arr1[0]));
	for (int i = 0; i < 10; i++)
		printf("%d ", arr1[i]);

	return 0;
}

注意:dst和src都要有超过num个字节的空间。
memcmp函数,C语言库函数篇,c语言,c++,数据结构,算法

my_memmove

memmove的模拟关键在于解决内存块重复部分移动问题。
首先要比较dst和src两个地址大小,原因如下:

  • 如果要将1 2 3 4 5 6 7 8的src 1 2 3 4移动到dst 3 4 5 6位置,就要从4开始倒着移动,才能避免重叠部分移动错误。
  • 如果要将src 3 4 5 6移动到dst 1 2 3 4位置,就要从3开始正着移动。
  • 如果不是重叠内存块拷贝,正着倒着移动都一样,地址位置判断并不影响。
void *my_memmove(void *dst, const void *src, int num)
{
	char *tmp_dst = (char *)dst;
	const char *tmp_src = (const char *)src;
	
	if (src > dst)
		for (int i = 0; i < num; i++)
			*tmp_dst++ = *tmp_src++;
	else
		for (int i = num-1; i >=0; i--)
			*(tmp_dst + i) = *(tmp_src + i);
			
	return dst;
}

三、memset 内存赋值函数

memset头文件:string.h
memset功能:给一片内存num个字节赋上指定值
memset函数声明:

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

ptr是内存块首字节地址。
value是要赋的值,这个值应该不超过一个无符号字节大小即28-1
num是需要赋值的字节数。
memset返回值是ptr首字节地址,并且是void*型,接收返回值需要强制类型转换。
memset使用实例:

#include <stdio.h>
#include <string.h>
int main()
{
	char carr[10] = { 0 };
	memset(carr, 65, sizeof(carr));
	printf("字符型:");
	for (int i = 0; i < 10; i++)
		printf("%c ",carr[i]);
		
	int darr[4] = { 0 };
	printf("\n整型:");
	memset(darr, 1,sizeof(darr));
	for (int i = 0; i < 4; i++)
		printf("%d ", darr[i]);
	return 0;
}

注意:
内存块要有num个字节大小。
给每个字节赋值,比如int型是4字节,赋值1,输出是16843009而不是1。

memcmp函数,C语言库函数篇,c语言,c++,数据结构,算法

my_memset

void *my_memset(void *ptr, int value, int num)
{
	//强制类型转换为无符号char*型
	unsigned char *tmp_ptr = (unsigned char *)ptr;
	//循环num次
	for (int i = 0; i < num; i++)
	{
		//因为char是特殊的整型,所以可以直接赋值
		*tmp_ptr++ = value;
	}

	return ptr;
}

四、memcmp 内存比较函数

memcmp头文件:string.h
memcmp功能:逐字节地比较从ptr1和ptr2开始的num个字节,直至比出。
memcmp函数声明:

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

ptr1是一个内存块首字节地址,ptr2是另一个内存块首字节地址。
num是需要比较的字节数。
ptr1>ptr2返回值>0,ptr1<ptr2返回值<0,完全相等返回值0。
memcmp使用实例:

#include <stdio.h>
#include <string.h>
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = { 1,2,3,4,5,7,7,7,7,7 };
	if (memcmp(arr1, arr2, sizeof(arr1)) > 0)
		printf("arr1大");
	else if (memcmp(arr1, arr2, sizeof(arr1)) < 0)
		printf("arr2大");
	else
		printf("arr1和arr2一样大");
	return 0;
}

注意:内存块要有num个字节大小。
memcmp函数,C语言库函数篇,c语言,c++,数据结构,算法

my_memcmp

int my_memcmp(const void *ptr1, const void *ptr2, int num)
{
	//先强制类型转换
	const char *tmp_ptr1 = (const char *)ptr1;
	const char *tmp_ptr2 = (const char *)ptr2;
	//循环num次,比较出就返回值
	for (int i = 0; i < num; i++)
	{
		if (*(tmp_ptr1+i) > *(tmp_ptr2+i))
			return 1;
		else if (*(tmp_ptr1+i) < *(tmp_ptr2+i))
			return -1;
	}
	//比较完num个字节了,仍没返回,完全相等返回值0。
	return 0;
}

熟练掌握库函数,敲码速度倍倍翻。
码字不容易,欢迎关注、点赞、收藏、评论、转发。文章来源地址https://www.toymoban.com/news/detail-687041.html

到了这里,关于【C语言】memcpy memmove memset memcmp 四大内存操作函数(详解+用法+模拟实现)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!

    ❤️ 博客主页: 小镇敲码人 🍏 欢迎关注:👍点赞 👂🏽留言 😍收藏 🌞 任尔江湖满血骨,我自踏雪寻梅香。 万千浮云遮碧月,独傲天下百坚强。 男儿应有龙腾志,盖世一意转洪荒。 莫使此生无痕度,终归人间一捧黄。🍎🍎🍎 ❤️ 我的努力求学没有得到别的好处,只

    2024年02月15日
    浏览(25)
  • memcpy、memmove、memcmp、memset函数的作用与区别

    作用: 从source的位置开始向后复制num个字节的数据到destination的内存位置。 注意: memcpy() 函数在遇到 ’\\0’ 的时候 不会停下来 (strcpy字符串拷贝函数在遇到’\\0’的时候会停下来); destination和source 所指向的内容不能重叠, 否则得不到想要的结果。 void* memcpy(void* destination

    2024年02月14日
    浏览(23)
  • C语言内存函数(memcpy、memmove、memcmp)详解

    memcpy函数为内存拷贝函数,既可以拷贝字符串,也可以拷贝整形数组、浮点型数组等,具有明显的应用优势, destination为目的地空间,source为不可修改(const)的来源空间,num表示无符号的字节数。其主要含义为将source内容拷贝到destination中,拷贝num个字节数。其返回类型、目

    2024年02月07日
    浏览(23)
  • 【C语言】内存函数memcpy和memmove的功能与模拟实现

    1.memcpy 功能:把source指向的前num个字节内容拷贝到destination指向的位置去,可以拷贝任意类型的数据。 注:1.memcpy并不关心\\0,毕竟传的也不一定是字符串,因此拷贝过程中遇到\\0也不会停下来。 2.num的单位是字节,并不是要拷贝的元素个数 3.如果source和destination有任何的重叠

    2024年02月19日
    浏览(34)
  • C语言—模拟实现memcpy,memmove

    函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。 这个函数在遇到 \\\'\\0\\\' 的时候并不会停下来。 如果source和destination有任何的重叠,复制的结果都是未定义的。 其实要实现memcpy非常的简单,我们不管传进来的是哪种数据类型都统一强转为char*,我们知

    2024年02月15日
    浏览(26)
  • 【C语言】memmove()函数(拷贝重叠内存块函数详解)

    🦄 个人主页 :修修修也 🎏 所属专栏 :C语言 ⚙️ 操作环境 : Visual Studio 2022 目录  一.memmove()函数简介 1.函数功能 2.函数参数 1.void * destination 2.onst void * source 3.size_t num 3.函数返回值 4.函数头文件 二.memmove()函数的具体使用 1.使用memmove()函数完成拷贝整型数组数据(目的地与源重

    2024年02月06日
    浏览(27)
  • 【C语言】memcpy()函数(内存块拷贝函数)

    🦄 个人主页 :修修修也 🎏 所属专栏 :C语言 ⚙️ 操作环境 : Visual Studio 2022 目录 一.memcpy()函数简介 🎏函数功能 🎏函数参数 📌void * destination 📌const void * source 📌size_t num 🎏函数返回值 🎏函数头文件 二.memcpy()函数的具体使用 🎏使用memcpy()函数完成拷贝整型数组数据 🎏使

    2024年02月05日
    浏览(28)
  • 提升内功之模拟实现库函数strlen/strncpy/strcmp/strcat/strstr/memcpy/memmove

    strlen函数的作用就是求字符串的首元素开始往后计算字符串的长度,直到’\\0‘,但不会把\\0的长度计算进去 strncpy的作用就是从source指向的字符串复制num个字节的内容到destination指向的字符串去 如果source的长度小于num,则填充0 注意source和destination的内容在空间上不要重叠,如

    2024年02月16日
    浏览(31)
  • memcpy内存拷贝函数

    目录 一、memcpy内存拷贝函数 注意事项 二、memcpy与strcpy对比 三、模拟实现memcpy函数 四、memcpy函数不能进行两块存在内存重叠的空间的内存拷贝 五、改进my_memcpy函数 头文件: string.h 函数原型: void* memcpy(void* destination , const void* source , size_t num) 函数作用: 将源地址中num个字节

    2024年02月07日
    浏览(29)
  • 【c++中内存拷贝函数(C++ memcpy)详解】

    原型 :void*memcpy(void*dest, const void*src,unsigned int count);  功能 :由src所指内存区域复制count个字节到dest所指内存区域。   说明 :src和dest所指内存区域不能重叠,函数返回指向dest的指针。     举例 :  下面自行实现这个函数 程序清单 1 V0.1版程序  程序清单 2 测试V0.1用例   

    2023年04月20日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包