【进阶C语言】内存函数(详解)

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

【进阶C语言】内存函数(详解)
前言

上一期讲的函数都是和字符串相关的,但是我们在操作数据的时候,不仅仅是操作字符串的数据,还得需要内存函数的应用


1. memcpy

1.1 memcpy的介绍

void * memcpy ( void * destination, const void * source, size_t num );
  1. 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
  2. 这个函数在遇到 ‘\0’ 的时候并不会停下来。
  3. 如果source和destination有任何的重叠,复制的结果都是未定义的。

1.2 memcpy的使用

用代码举例:

int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[8] = { 0 };
	//把arr1中的前5个数据拷贝到arr2中
	memcpy(arr2, arr1, 20);//strcpy不能用,它只针对字符串拷贝,而上面的是整型数据
	return 0; 
}

【进阶C语言】内存函数(详解)
试试浮点型看看可不可以:

int main()
{
	float arr1[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
	float arr2[8] = { 0 };
	//把arr1中的前5个数据拷贝到arr2中
	memcpy(arr2, arr1, 12);
	return 0; 
}

【进阶C语言】内存函数(详解)

从中发现memcpy它并不在乎整型还是浮点型,所以叫他内存拷贝

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

在分析一下上面的信息:
void* – 通用类型的指针,可以接受任意类型数据的地址,但是这种指针不能直接解引用和加减运算!
memcpy函数的设计者,不知道未来程序员使用memcpy拷贝什么类型的数据!
size_t num 表示拷贝多少个字节

1.3 模拟实现memcpy库函数

//memcpy函数返回的是目标空间的起始地址
#include <assert.h>

void* my_memcpy(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest && src);
	while (num--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[8] = { 0 };
	//把arr1中的前5个数据拷贝到arr2中
	my_memcpy(arr2, arr1, 20);
	return 0; 
}

调试监视结果如下:

【进阶C语言】内存函数(详解)

1.4 我想在1,2后面打印1,2,3,4,5会怎么样?

#include <assert.h>

void* my_memcpy(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest && src);
	while (num--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	//   你先打印  1 2 1 2 3 4 5 8 9 10
	//   结果却是  1 2 1 2 1 2 1 8 9 10
	
	my_memcpy(arr1 + 2, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
}

【进阶C语言】内存函数(详解)
红色框框:目标空间
绿色框框:想要拷贝的原数据

结论:
所以我们发现:在内存重叠的时候,使用memcpy可能会出现意想不到的结果
建议在内存重叠的情况,使用memmove函数.

2. memmove

2.1 memmove的介绍

void * memmove ( void * destination, const void * source, size_t num );
  1. 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
  2. 如果源空间和目标空间出现重叠,就得使用memmove函数处理。

2.2 memmove的使用

int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	//   你先打印  1 2 1 2 3 4 5 8 9 10
	//   结果却是  1 2 1 2 3 4 5 8 9 10
	//说明没有问题
	
	memmove(arr1 + 2, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
}

代码结果:
【进阶C语言】内存函数(详解)

2.3 模拟实现memmove库函数

【进阶C语言】内存函数(详解)
红色框框:目标空间
蓝色框框:想要拷贝的原数据
【进阶C语言】内存函数(详解)
当dest在src前面,也就是dest的地址更低,src的地址更高的时候
【进阶C语言】内存函数(详解)
整个图片概念图:
【进阶C语言】内存函数(详解)
从而有两种方案,综合比较,B方案效果更好
【进阶C语言】内存函数(详解)
B方案图片解释:
【进阶C语言】内存函数(详解)
代码样子:

if (dest < src)
{


	//前->后



}
else
{

	//后->前


}

完整版代码:

//memcpy函数返回的是目标空间的起始地址
#include <assert.h>

void* my_memmove(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest && src);
	if (dest < src)
	{
		//前->后
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		//后->前
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	return ret;
}

int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	//             1 2 1 2 3 4 5 8 9 10
	my_memmove(arr1 + 2, arr1, 20);
	//my_memmove(arr1, arr1+2, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
}

总结:
C语言:memcpy拷贝不重叠的内存
重叠的就交给memmove
memmove > memcpy 100 60
VS:100 100

3. memcmp

3.1 memcmp的介绍

int memcmp ( const void * ptr1,  const void * ptr2,  size_t num );
  1. 比较从ptr1和ptr2指针开始的num个字节
  2. 返回值如下:【进阶C语言】内存函数(详解)

3.2 memcmp的使用

int main()
{
	int arr1[] = { 1,2,3,4,5 };//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00
	int arr2[] = { 1,2,3,4,6 };//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 06 00 00 00
	int ret = memcmp(arr1, arr2, 17);
	printf("%d\n", ret);
}

代码结果:
【进阶C语言】内存函数(详解)

4. memset

4.1 memset的介绍

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

将 ptr 指向的内存块的第一个字节数设置为指定值(解释为无符号字符)。

4.2 memset的使用

int main()
{
	char arr[] = "hello world";//以字节为单位来进行设置的
		memset(arr, 'x', 5);
		printf("%s\n", arr);
}

代码结果:
【进阶C语言】内存函数(详解)
注意:memset是以字节为单位来进行设置的!!
什么意思呢?

int main()
{
	int arr[10] = { 0 };
	//01 01 01 01
	memset(arr, 1, sizeof(arr));//这种写法无法将数据的每个元素设置为1
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%x ", arr[i]);
	}
}

体会代码结果:

这种写法无法将数据的每个元素设置为1

【进阶C语言】内存函数(详解)

如果这份博客对大家有帮助,希望各位给恒川一个免费的点赞作为鼓励,并评论收藏一下,谢谢大家!!!
制作不易,如果大家有什么疑问或给恒川的意见,欢迎评论区留言。文章来源地址https://www.toymoban.com/news/detail-400427.html

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

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

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

相关文章

  • C语言内存函数详解

    本章内容主要讲解:memcpy(内存拷贝函数),memmove(内存移动函数),memcmp(内存比较函数)的 基本作用 和 模拟实现 。 1.memcpy函数 函数功能:从source指向的内存空间处拷贝num个字节的内容到destination指向的内存中, 当拷贝的内容是 \\\'\\0\\\' 时,函数不会主动停下来,除非拷贝的内容达

    2024年02月14日
    浏览(37)
  • C语言-内存函数详解

    返回类型和参数: 1.函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。 2.这个函数在遇到 ‘\\0’ 的时候并不会停下来。 3. 如果source和destination有任何的重叠,复制的结果都是未定义的。 4.注意单位是字节 5.头文件:#includestring.h memcpy使用: 运行

    2024年02月05日
    浏览(40)
  • C语言-详解内存函数

    它的函数原型如下: 具体的函数介绍如下: 好,相信同学们看了这个函数,应该是能够简单了解函数中各个参数的用法。 下面我们来总结一下: 函数 memcpy 从 source 的位置开始向后复制 num 个字节的数据到 destination 指向的内存位置。 这个函数在遇到 \\\'\\0\\\' 的时候并不会停下来。

    2024年04月16日
    浏览(54)
  • 【C语言】free()函数详解(动态内存释放函数)

    🦄 个人主页 :修修修也 🎏 所属专栏 :C语言 ⚙️ 操作环境 : Visual Studio 2022 目录  一.free()函数简介 1.函数功能 2.函数参数 void * ptr 3.函数返回值 4.函数头文件 二.free()函数的具体使用 1.使用free()函数完成malloc()开辟空间的释放 2.使用free()函数完成calloc()开辟空间的释放 3.使用

    2024年02月08日
    浏览(39)
  • 【C语言进阶】⑥函数指针详解

    1.概念 函数指针 :首先它是一个指针,一个指向函数的指针,在内存空间中存放的是函数的地址; 请看示例: 解析:parr是一个指向数组的指针,存放的是数组的地址; 所以: 数组指针 —存放数组地址的指针; 数组名 —得到的就是数组的地址; 那么我们可以不可以这么认

    2024年02月02日
    浏览(37)
  • 【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日
    浏览(38)
  • 【进阶C语言】qsort库函数(详解)

    qsort是C语言库函数里面的一种,包含于#include stdlib.h这个头文件里面,使用快速排序的方法 qsort英语解析:Quick sort,翻译就是快速排序,它的内部实现是通过的快速排序算法来实现的。 功能:对传入的任何数据进行排序,使其变成有序数列。 qsort是可以排序任意类型的数据

    2024年02月02日
    浏览(43)
  • 【进阶C语言】字符函数和字符串函数(万文详解)

    前言 C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者字符数组中。 字符串常量适用于那些对它不做修改的字符串函数. 今天将带来C语言函数的使用介绍 分为三部分供大家理解 如果这份博客对大家有帮助,希望

    2024年01月18日
    浏览(65)
  • C语言内存函数(memcpy、memmove、memcmp)详解

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

    2024年02月07日
    浏览(35)
  • C语言之字符串,内存操作函数详解(一)

    💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C语言学习分享⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习更多C语言知识   🔝🔝 C语言的标准库为我们提供了丰富的字符串操作函数与内存操作函数,有我们熟悉的 strlen ,strcpy ,也有我们不熟悉的 strchr , strstr 等

    2024年02月08日
    浏览(77)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包