C语言内存函数详解

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

内存函数

本章内容主要讲解:memcpy(内存拷贝函数),memmove(内存移动函数),memcmp(内存比较函数)的基本作用模拟实现

C语言内存函数详解,零基础C语言之路,c语言,算法,开发语言

1.内存函数的介绍

1.memcpy函数

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

函数功能:从source指向的内存空间处拷贝num个字节的内容到destination指向的内存中,当拷贝的内容是'\0'时,函数不会主动停下来,除非拷贝的内容达到了num个字节。

使用案例:将arr2数组拷贝进arr1数组。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main()
{
	int arr1[10] = { 0 };
	int arr2[10] = { 1,2,3,4,5,6,7,8,9,10 }; 
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	memcpy(arr1, arr2, sizeof(arr2));
	printf("\n");
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

C语言内存函数详解,零基础C语言之路,c语言,算法,开发语言

注意destination和source最好不要指向同一个内存空间,否则结果会变得不可控。

当destination和source指向同一块内存空间时,结果会变得不可控:

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	memcpy(arr+1, arr, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
    //arr数组经过拷贝之后:1,1,2,3,4,5,7,8,9,10
	return 0;
}

C语言内存函数详解,零基础C语言之路,c语言,算法,开发语言

在较低版本的编译器中,memcpy的拷贝方式是将source中的内容由低地址向高地址开始依次拷贝进destination的内存空间中,通俗来讲就是从前向后拷贝,但这种拷贝方式是有弊端的。例如这里,destination是arr+1,source是arr。拷贝的空间为20个字节,也就是5个整型,预期结果应该就是如图的运行结果。但是在较低版本的编译器中却不是如此的结果。

分析这里先将1移动到2的位置,2被覆盖。接着应该是将2这个值给移动到3这里,但是2已经被修改为1了,所以此时实际上是将1把3给覆盖掉了,这这样一直持续到结束。结果就变成了[1,1,1,1,1,1,7,8,9,10]。所以此时这种指向同一内存空间的情况时,就需要用到memmove函数了

解决方案:此时就需要从后向前拷贝了。这样就不会覆盖src中待拷贝的内容了。

那么就不难看出:

当src>des时,就使用从后向前拷贝的方式。

当src<=des时,就使用从前向后的拷贝方式。

(这也就是memmove函数的内核,memmove函数会根据src和des的大小,选择不同的拷贝方式)

C语言内存函数详解,零基础C语言之路,c语言,算法,开发语言

注意:这里由于我使用的visual studio是2022版本,所以这个问题就被规避了,但是倘若使用的较低版本的visual studio编译器,例如:2019版本的,其运行结果并不在我们的预期之中。

2.memmove函数

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

函数功能:与memcpy函数的功能一样,不过区别是memmove函数处理的源内存块和目标内存块是可以重叠的当destination和source指向的内存空间会发生重叠的可能性时,就得使用memmove函数进行处理。

使用案例

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

C语言内存函数详解,零基础C语言之路,c语言,算法,开发语言

3.memcmp函数

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

函数功能:比较从ptr1和ptr2指针指向的前num个字节的内容。

返回值:

  • 若ptr1大于ptr2,返回一个大于0的数
  • 若ptr1等于ptr2,返回0
  • 若ptr1小于ptr2,返回一个小于0的数

使用案例:(比较两个字符串前6个字节的内容)

#include<stdio.h>
#include<stdlib.h>
int main()
{
	char* p1 = "abcdef";
	char* p2 = "abbcde";
	printf("%d ", memcmp(p1, p2, 6));
	return 0;
}

C语言内存函数详解,零基础C语言之路,c语言,算法,开发语言

2.内存函数的模拟实现

1.memcpy函数的模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
void* my_memcpy(void* des,const void* src,size_t num)
{
    void* ret = des;
	assert(des);
	assert(src);
	while (num--)
	{
		*(char*)des = *(char*)src;
		des = (char*)des + 1;
		src = (char*)src + 1;
	}
    return ret;
}

注意这里由于memcpy函数的前两个参数都是void*类型,所以需要转化成char*进行逐字节赋值比较方便。

C语言内存函数详解,零基础C语言之路,c语言,算法,开发语言

2.memmove函数的模拟实现

当src>des时,就使用从后向前拷贝的方式。

当src<=des时,就使用从前向后的拷贝方式。

(这也就是memmove函数的内核,memmove函数会根据src和des的大小,选择不同的拷贝方式)

void* my_memmove(void* des, const void* src, size_t num)
{
	void* ret = des;
	if (des < src)//容易将src给改变,所以就是从后向前拷贝
	{
		while (num--)
		{
			*((char*)des + num) = *((char*)src+num);
		}
	}
	else//从前向后拷贝
	{
		while (num--)
		{
			*(char*)des = *(char*)src;
			des = (char*)des + 1;
			src = (char*)src + 1;
		}
	}
	return des;
}

3.memcmp函数的模拟实现

int my_memcmp(const void* des, const void* src, size_t num)
{
	assert(des);
	assert(src);
	while (*(char*)des == *(char*)src && num--)
	{
		des = (char*)des + 1;
		src = (char*)src + 1;
	}
	if (num == 0)
		return 0;
	else
	return (*(char*)des - *(char*)src);
}

3.完结

本章的内容就到这里啦,若有不足,欢迎评论区指正,下期见!文章来源地址https://www.toymoban.com/news/detail-625378.html

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

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

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

相关文章

  • 【C语言基础】:内存操作函数

             书山有路勤为径,学海无涯苦作舟。 创作不易,宝子们!如果这篇文章对你们有帮助的话,别忘了给个免费的赞哟~ 一、memcpy函数的使用和模拟实现 函数原型 : 内存复制块 将num字节的值从源指向的位置直接复制到目标指向的内存块。 源指针和目标指针所指向的对

    2024年04月11日
    浏览(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语言之字符串,内存操作函数详解(一)

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

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

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

    2024年02月07日
    浏览(32)
  • 【C语言】memcpy memmove memset memcmp 四大内存操作函数(详解+用法+模拟实现)

    头文件string.h中常用内存操作函数共有四大,学习完本篇文章,各种类型数组的常见处理轻松拿下。 对字符串(字符数组)的操作函数有很多,但是我们想要操作整型数组等呢: 这就需要内存操作函数了, memory在计算机科学中是内存的意思 ,这也是四大内存操作函数都有mem头

    2024年02月10日
    浏览(47)
  • C++语言基础——函数(详解)

    目录 函数是什么 函数的定义 主函数举例  空函数 函数的调用 语法格式 举例说明:计算x的n次方 递归 递归的主要点 递归的结构 条件 递归使用的场景 函数全名叫 计算机函数 ,它可以帮助你完成一些特定的程序。你可以把它简单理解成一把手枪。 手枪的作用: 完成几发子

    2024年01月21日
    浏览(56)
  • c语言基础知识帮助理解(详解函数)

    目录 1. 函数是什么 2. 库函数  3. 自定义函数  4. 函数参数  4.1实际参数(实参)  4.2形式参数(形参)  5.函数的调用 5.1传值调用 5.2传址调用 (传递地址) 6. 函数的嵌套调用和链式访问  6.1 嵌套调用  6.2 链式访问  7. 函数的声明和定义  7.1 函数声明  7.2函数定义 函数是

    2024年02月14日
    浏览(43)
  • c语言基础知识帮助理解(函数递归详解)

    \\\"从前有座山,山里有座庙,庙里有个老和尚和一个小和尚。有一天老和尚对小和尚说:“从前有座山.山里有座庙,庙里有个老和尚和一个小和尚,有一天老和尚对小和尚说:“从前有座山.山里有座庙,庙里有个老和尚和一个小和尚......\\\" (虽能体现递归特点,但又不是递归)

    2024年02月14日
    浏览(39)
  • C语言格式化输出函数printf详解——C语言基础知识

    (由于篇幅较长,内容较全,建议收藏) printf函数的一般格式为: printf(格式控制字符串,输出值参数表); 如: 其中, f=%f,c=%fn 是 格式控制字符串 , f,c 是 输出值参数表 。 (1)格式控制字符串是用双引号括起来的字符串,包括三类信息: 格式字符。格式字符由“%”

    2023年04月08日
    浏览(40)
  • 【Go 基础篇】Go语言匿名函数详解:灵活的函数表达式与闭包

    在Go语言中,函数是一等公民,这意味着函数可以像其他类型的值一样被操作、传递和赋值。匿名函数是一种特殊的函数,它没有固定的函数名,可以在代码中被直接定义和使用。匿名函数在Go语言中具有重要的地位,它们常用于实现闭包、函数式编程和并发编程等领域。 本

    2024年02月11日
    浏览(51)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包