【C】剖析C语言内存函数

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

前言:

上一篇文章详细介绍了字符串函数,那字符串函数和内存函数到底有什么区别呢?

最根本的区别在于,他们操作的对象不同,视角不同。

字符串函数针对的是一个个的字符,而内存函数顾名思义关注的是内存,存储在内存中的一个个字节。

一、memcpy函数

【C】剖析C语言内存函数,C语言,c语言,内存函数

功能:

复制内存块,可以将任意类型的数据进行拷贝。

将source的num个字节的内容拷贝到destination内存中

参数和返回值:

前面两个参数分别是目标内存的起始地址和源内存的起始地址,第三个参数是需要拷贝内容的字节个数

返回值是destination的首元素地址

头文件:

#include <string.h>

与strcpy的区别

  • memcpy不需要考虑' \0 '的问题,因为操作对象就是内存,视角不同
  • memcpy可以拷贝任意类型的数据,而strcpy只能拷贝字符的数据

注意事项:

  • 因为要接收任意类型的指针数据,所以函数参数类型就是void*
  • 如果source和destination有任何的重叠,复制的结果都是未定义的,容易拷贝已经重叠的内容。

模拟实现:

char* my_memcpy(void* dest, const void* sou, size_t num)
{
	void* ret = dest;
	while (num--)
	{
		*(char*)dest = *(char*)sou;
		//(char*)dest++;
		dest = (char*)dest + 1;
		sou = (char*)sou + 1;
	}
	return ret;
}


int main()
{
	int arr1[20] = { 0 };
	int arr2[] = { 1,2,3,4,5,6,7 };
	my_memcpy(arr1, arr2, 21);
	for (int i=0;i<10;i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}
灵魂总结:
  • 如果函数的参数可以接收任意类型的数据,那么设置这种函数参数一般用void*
  • 如果函数可以对任意类型的数据进行改变,并且根据字节的个数来决定,那么函数参数的类型设置为char*

二、memmove函数

【C】剖析C语言内存函数,C语言,c语言,内存函数

功能:

与memcpy函数功能相似,但是memmove函数功能更强大,可以拷贝带有重叠的内存块,因此我们以后可以直接采用memmove函数去拷贝内容,不论是重叠或不重叠 。

TIP:memcpy和memmove的渊源:

为何memcpy函数拷贝重叠的字符串会有问题呢?

【C】剖析C语言内存函数,C语言,c语言,内存函数 比如我们有这样的一段内存,然后soul为起始地址,传3个整型(12个字节)到dest位置上。

但是如果用memcpy拷贝的方法,发现已经先把1覆盖到了3的位置,所以3就变成了1,之后再想拷贝3发现已经被覆盖为1,所以此法不通。

解决方法: 

我们可以从后向前拷贝,先将sou最后的3拷贝到dest最后的5,接着再向前拷贝,这样就避免了重叠的问题

新的问题:

【C】剖析C语言内存函数,C语言,c语言,内存函数

 还是一样的需求,把sou为起始地址,传3个整型(12个字节)到dest位置上。

但这时再从后向前拷贝,会将3重叠为5,之后再想拷贝3,就会变成5.

解决方法:

我们从前向后拷贝,从sou的3开始拷贝,这样也避免了重叠问题。

总结:

遇到不同的情况,我们采取不同的措施,分情况的标准就是sou,和dest的地址高低,若sou<dest,我们就采用从后向前拷贝,若sou>dest,我们就采用从前向后的拷贝方法。

模拟实现memmove函数

#include<assert.h>

void* my_memmove(void* dest, void* soul, size_t num)
{
	void* ret = dest;
	if (soul < dest)
	{
		dest = (char*)dest + num-1;//需要减去1,因为+1就是两个字节了
		soul = (char*)soul + num-1;
		while (num--)
		{
			*(char*)dest = *(char*)soul;
			dest = (char*)dest - 1;
			soul = (char*)soul - 1;
		}
	}
	else
	{
		while (num--)
		{
			*(char*)dest = *(char*)soul;
			dest = (char*)dest + 1;
			soul = (char*)soul + 1;
		}
	}
	return ret;
}

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

三、memcmp函数

【C】剖析C语言内存函数,C语言,c语言,内存函数

功能:

两个指针指向的内容进行比较,并从起始位置往后的num个字节内容进行比较

参数和返回值:

参数为两个指针,并且加上限制字节的个数

返回值,如果前者大于后者,返回大于0的数字,如果前者小于后者,返回小于0的数字,两者相等,返回0。

注意:

  • 可以比较任意类型的数据
  • 比较的方式就是一个字节的内容和另一个字节的内容进行比较

四、memset函数

【C】剖析C语言内存函数,C语言,c语言,内存函数

功能:

字节为单位,将ptr指向的内容修改为num个字节的value值 

实操:

【C】剖析C语言内存函数,C语言,c语言,内存函数

上面是char类型,下面是int类型,int类型更便于我们理解

 【C】剖析C语言内存函数,C语言,c语言,内存函数

时时刻刻要想到内存函数操作的对象是字节,比如上面的整型例子,memset操作了10个字节,相当于把两个整型的内容改成01 01 01 01,然后第三个元素改成01 01 00 00文章来源地址https://www.toymoban.com/news/detail-588107.html

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

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

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

相关文章

  • 【C语言进阶】——深入剖析数据在内存中的存储

    到目前为止,我们已经掌握了C语言的基本内置类型,如下: 每一种数据类型的大小不同,这也就决定了它所存储的数据范围也就不同,就比如char和int所存储的数据范围就不同,那么具体能存储多少呢?相信大家看完本本章内容,就能对每一种数据是怎么存储在内存中的,就

    2024年02月19日
    浏览(47)
  • 进阶C语言-深度剖析数据在内存中的存储

    📝通过前面的学习,我们已经学习了基本的内置类型: 🔎 类型的意义 : 使用这个类型开辟内存空间的大小。 如何看待内存空间的视角。 🔭 整形家族 : 🔭 浮点数家族 : 🔭 构造类型(自定义类型) : 🔭 指针类型 : 🔭 空类型 : void 表示空类型(无类型) 通常用于

    2024年02月09日
    浏览(34)
  • 剖析C语言字符串函数

    目录 前言: 一、strlen函数 功能: 参数和返回值: 注意事项: 返回值是无符号的易错点: strlen函数的模拟实现 1、计数器算法 2、递归算法 3、指针减去指针 二、strcpy函数 功能: 参数和返回值 注意事项: strncpy函数 strcpy函数的模拟实现 三、strcat函数  功能: 参数和返回值

    2024年02月16日
    浏览(31)
  • 【C语言】剖析qsort函数的实现原理

    主页:17_Kevin-CSDN博客 专栏:《C语言》 本文将从回调函数,qsort函数的应用,qsort函数的实现原理三个方面进行讲解,请自行跳转至相对位置进行阅读~  目录 回调函数 qsort函数的应用 qsort函数实现原理 回调函数实际上是一个指针,指向的是一个函数。它作为一个参数传递给

    2024年03月14日
    浏览(32)
  • C语言-------函数栈帧的创建和销毁------剖析描骨

    🎂        ✨✨✨✨✨✨🍧🍧🍧🍧🍧🍧🍧🎂    🎂      作者介绍:                              🎂🎂        🎂 🎉🎉🎉🎉🎉🎉🎉              🎂           🎂作者id:老秦包你会,         🎂 简单介绍:🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂

    2024年02月14日
    浏览(33)
  • C语言 — 动态内存管理(动态内存函数)

    本期分为三篇介绍动态内存管理相关内容,关注博主了解更多 博主博客链接:https://blog.csdn.net/m0_74014525 本期介绍动态内存函数,函数如何使用、函数格式、在使用在所需要的注意点及C/C++程序的内存开辟区域 第一篇:C语言 — 动态内存管理(动态内存函数) 第二篇:C语言

    2024年02月14日
    浏览(45)
  • 【C语言】字符函数和内存操作函数

    大家好,我是苏貝,本篇博客带大家了解字符函数和内存操作函数,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 下面函数的头文件都是ctype.h 函数 如果他的参数符合下列条件就返回真即非0,不符合则返回0 iscntrl 任何控制字符 isspace 空白字符:空格‘ ’

    2024年02月08日
    浏览(45)
  • 【C语言】字符函数,字符串函数,内存函数

    大家好!今天我们来学习C语言中的字符函数,字符串函数和内存函数。 目录 1. 字符函数 1.1 字符分类函数 1.2 字符转换函数 1.2.1 tolower(将大写字母转化为小写字母) 1.2.2 toupper(将小写字母转化为大写字母) 2. 字符串函数 2.1 字符串输入函数 2.1.1 gets() ​2.1.2 fgets() 2.2 字符串

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

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

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

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

    2024年02月05日
    浏览(37)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包