【C语言】内存函数的详细教学和模拟实现

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

🚀write in front🚀
🔎大家好,我是gugugu。希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎
🆔本文由 gugugu 原创 CSDN首发🐒 如需转载还请通知⚠
📝个人主页:gugugu—精品博客
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​
📣系列专栏:gugugu的精品博客
✉️我们并非登上我们所选择的舞台,演出并非我们所选择的剧本📩

【C语言】内存函数的详细教学和模拟实现,技术栏,博客创作,小白教学,c语言
vs 启动

前言

上一篇博客里讲到了字符函数和字符串函数,那么在这一篇博客中,我们将另一种常见的函数讲解一下,就是内存函数,内存函数比字符函数和字符串函数更加的广泛,毕竟是针对内存的函数。
【C语言】内存函数的详细教学和模拟实现,技术栏,博客创作,小白教学,c语言

一、内存函数与字符串函数的区别

C语言内存函数,是针对内存块的,不在乎内存中的数据,但是字符串函数时针对字符串的,在乎内存中的数据,只操作字符串,与\0操作符关系密切。

二、memcpy函数

memcpy函数与strcpy函数功能比较相似,都是进行拷贝操作,但是memcpy针对的对象不同。

1、memcpy函数的基本结构

void* memcpy(void * destination ,const void * source,size_t num);
函数有三个参数,分别为起始地址,目标地址和移动的字节的大小,返回值是void*

  • 那么为什么起始地址和目标地址,以及返回值都是void类型呢?

【C语言】内存函数的详细教学和模拟实现,技术栏,博客创作,小白教学,c语言

因为memcpy函数针对的对象是内存空间,而内存空间中储存的数据类型不清楚,有多种可能性,所以直接使用void*类型的指针,在使用时,进行强制类型转换。

另外,在这里补充一点
在上一篇文章里面,很多字符串函数的返回值都是一个指针,这是为什么呢?

【C语言】内存函数的详细教学和模拟实现,技术栏,博客创作,小白教学,c语言

其实,这是为了能够通过返回值去更方便的进行链式访问

2、memcpy函数的模拟实现

在模拟实现memcpy这些内存函数的时候,主要是要注意对void*的强转,这比较巧妙。

这里提供两种方法。大同小异
方法一

#include <stdio.h>
#include <assert.h>

void* my_memcpy(void* ch1, const void* ch2, size_t num)
{
    assert(ch1 && ch2);
    void* ret = ch1;
    int i = 0;
    for (i = 0; i < num; i++)
    {
        *((char*)ch1)++ = *((char*)ch2)++;
    }
    return ret;
}


int main()
{
    int arr1[10] = { 0 };
    int arr2[] = { 1,2,3,4,5,6,7,8 };
void * ret1=my_memcpy(arr1, arr2, 20);
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        printf("%d ", *(((int*)ret1)++));
    }
    printf("\n");

    char ch1[] = "ZZZZZZZZZZZ";
    char ch2[] = "YYYYYYYYY";
    void * ret2=my_memcpy(ch1, ch2, 6);
    printf("%s\n", (char *)ret2);
    return 0;
}

方法二

#include <stdio.h>
#include <assert.h>

void* my_memcpy(void* ch1, const void* ch2, size_t num)
{
    assert(ch1 && ch2);
    void* ret = ch1;
    while (num--)
    {
        *(char*)ch1 = *(char*)ch2;
        ch1 = (char*)ch1 + 1;
        ch2 = (char*)ch2 + 1;
    }
    return ret;
}


int main()
{
    int arr1[10] = { 0 };
    int arr2[] = { 1,2,3,4,5,6,7,8 };
void * ret1=my_memcpy(arr1, arr2, 20);
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        printf("%d ", *(((int*)ret1)++));
    }
    printf("\n");

    char ch1[] = "ZZZZZZZZZZZ";
    char ch2[] = "YYYYYYYYY";
    void * ret2=my_memcpy(ch1, ch2, 6);
    printf("%s\n", (char *)ret2);
    return 0;
}

memcpy函数针对的对象是内存空间,所以对整形和字符都可以处理

三、memmove函数

1、memmove函数的优势

memcpy函数在使用时会存在问题,比如目标空间和起始空间发生了重叠,此时使用memcpy函数就会出现问题。
看下面的例子
【C语言】内存函数的详细教学和模拟实现,技术栏,博客创作,小白教学,c语言

#include <stdio.h>
#include <assert.h>

void* my_memcpy(void* ch1, const void* ch2, size_t num)
{
    assert(ch1 && ch2);
    void* ret = ch1;
    while (num--)
    {
        *(char*)ch1 = *(char*)ch2;
        ch1 = (char*)ch1 + 1;
        ch2 = (char*)ch2 + 1;
    }
    return ret;
}

int main()
{
    int arr[10] = { 1,2,3,4,5,6,7 };
    my_memcpy(arr + 2, arr, 20);
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}

按照设想,答案应该是 1 2 1 2 3 4 5 0 0 0
但是实际答案是
【C语言】内存函数的详细教学和模拟实现,技术栏,博客创作,小白教学,c语言
是不是没想到?
【C语言】内存函数的详细教学和模拟实现,技术栏,博客创作,小白教学,c语言

这是为什么呢?
主要是在实现的时候,读取到第三个数的时候,本来是3,但是被赋值之后就变成了1,所以第三个数也就成了1,而不是三,后面也是一样。

但是memmove函数可以解决这个问题
【C语言】内存函数的详细教学和模拟实现,技术栏,博客创作,小白教学,c语言

2、memmove函数的模拟实现

像上面实现memcpy一样从前面向后面拷贝出现了问题,那么如果从后面往前面拷贝,又当如何?
【C语言】内存函数的详细教学和模拟实现,技术栏,博客创作,小白教学,c语言

这是就会先将5放到arr[6]上,4放到arr[5]上,依次类推,可以发现,不会出现问题。

但是又有新的问题,如果是memmove(arr,arr+2,20),这又会怎么办呢?

这是从后往前就不行了,就得从前往后拷贝。

聪明的小伙伴,看到这里肯定能够想出解决方案。

  • 当目的地址比起始地址大时,从后往前拷贝
  • 当目的地址比起始地址小时,从前往后拷贝

上代码
【C语言】内存函数的详细教学和模拟实现,技术栏,博客创作,小白教学,c语言

#include <stdio.h>
#include <assert.h>
void* my_memmove(void* ch1, const void* ch2, size_t num)
{
    assert(ch1 && ch2);
    void* ret = ch1;
    if (ch1 > ch2)
    {
        while (num--)//自减操作后num已经是19了
        {
            *((char*)ch1 + num) = *((char*)ch2 + num);//每次自减操作后,num都会少1,向前走了一个字节
        }
    }
    else
    {
        while (num--)
        {
            *(char*)ch1 = *(char*)ch2;
            ch1 = (char*)ch1 + 1;
            ch2 = (char*)ch2 + 1;
        }
    }
    return ret;
}

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

四、memset函数

这个函数比较简单,就不详细讲解了
【C语言】内存函数的详细教学和模拟实现,技术栏,博客创作,小白教学,c语言

1、memset函数的功能

set的意思是设置,我们在这里把它理解成赋值,就是给内存去赋值

先写段代码看看功能吧

#include <stdio.h>

int main()
{
	char ch[20] = "hello world!";
	memset(ch, 'x', 10);
	printf("%s\n", ch);
	return 0;
}

【C语言】内存函数的详细教学和模拟实现,技术栏,博客创作,小白教学,c语言
需要注意的是

memset函数的结构比较特殊
void * memset(void* ptr,int value,size_t num);
第二个参数是int类型,为啥我的例子里面给的是char呢?

是因为char是使用ASCII码值进行操作的。

2、memset函数的模拟实现

比较简单,直接上代码

#include <stdio.h>
#include <assert.h>
void* my_memset(void* ch, int value ,size_t num)
{
	assert(ch);
	void* ret = ch;
	while (num--)
	{
		*(char*)ch = value;
		ch = (char*)ch + 1;
	}
	return ret;
 }
int main()
{
	char ch[20] = "hello world!";
	my_memset(ch, 'x', 10);
	printf("%s\n", ch);
	return 0;
}

【C语言】内存函数的详细教学和模拟实现,技术栏,博客创作,小白教学,c语言
运行成功,yeah

五、memcmp函数

这个函数也比较简单,就是对内存进行比较

1、memcmp函数的基本结构

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

  • 返回值是int 跟strcmp一样
  • 两个指针参数都加上了const ,无法修改内容
  • num是比较的字节数

2、memcmp函数的模拟实现

比较简单,直接上代码
【C语言】内存函数的详细教学和模拟实现,技术栏,博客创作,小白教学,c语言

#include <stdio.h>
#include <assert.h>
int my_memcmp(const void* ptr1, const void* ptr2, size_t num)
{
	assert(ptr1 && ptr2);
	while (num--)
	{
		if (*(char*)ptr1 == *(char*)ptr2)
		{
			ptr1 = (char*)ptr1 + 1;
			ptr2 = (char*)ptr2 + 1;
		}
		else
			return *(char*)ptr1 - *(char*)ptr2;
	}
	return 0;
}
int main()
{
	char ch1[20] = { 0 };
	char ch2[20] = { 0 };
	gets(ch1);
	gets(ch2);
	int num = 0;
	scanf("%d", &num);
	int ret = my_memcmp(ch1, ch2, 5);
	if (ret > 0)
		printf(">\n");
	else if (ret < 0)
		printf("<\n");
	else
		printf("==\n");
	return 0;
}


ok ,这次的分享到这里就结束了,函数的内容基本上就要告一段落了

今天下午还会有一更哦,敬请关注!!!


!!!!!!!!!!!!!!!!!求关注!!!!!!!!!!!!!!!!

!!!!!!!!!!!!!!!蹲个一键三连!!!!!!!!!!!!!!!

【C语言】内存函数的详细教学和模拟实现,技术栏,博客创作,小白教学,c语言文章来源地址https://www.toymoban.com/news/detail-727617.html

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

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

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

相关文章

  • 【C语言】内存函数memcpy和memmove的功能与模拟实现

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

    2024年02月19日
    浏览(40)
  • C语言从入门到实战——常用内存函数的了解和模拟实现

    内存函数(memory functions)指的是控制计算机内存操作的函数 函数 memcpy 从 source 的位置开始向后复制 num 个字节的数据到 destination 指向的内存位置。 这个函数在遇到 \\\'\\0\\\' 的时候并不会停下来。 如果 source 和 destination 有任何的重叠,复制的结果都是未定义的。 对于重叠的内存

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

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

    2024年02月10日
    浏览(47)
  • C语言内存操作函数,memcpy的使用和模拟实现,memmove的使用和模拟实现,memcmp的使用,memset的使用。

    函数原型: void *dest 目标数据首元素地址 const void *src 源数据(需要拷贝过去的数据) size_t count 需要拷贝数据的字节大小 void *memcpy 拷贝结束后,返回目标数据的起始地址 函数作用: 拷贝 count 个字节的数据从源数据起始地址到目标空间。 函数的使用 函数的模拟实现: 注:

    2024年02月09日
    浏览(44)
  • c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(下))

    上篇文章介绍了一些常用的字符串函数,大家可以跳转过去浏览一下:c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(上))_总之就是非常唔姆的博客-CSDN博客 今天接着来介绍一些:  目录 一.字符串查找 1.strstr() 1.1示例 1.2注意事项: 1.3模拟实现  2.

    2024年02月07日
    浏览(45)
  • 一篇博客学会系列(1) —— C语言中所有字符串函数以及内存函数的使用和注意事项

    目录 1、求字符串长度函数 1.1、strlen 2、字符串拷贝(cpy)、拼接(cat)、比较(cmp)函数 2.1、长度不受限制的字符串函数 2.1.1、strcpy 2.1.2、strcat 2.1.3、strcmp 2.2、长度受限制的字符串函数 2.2.1、strncpy 2.2.2、strncat 2.2.3、strncmp 3、字符串查找函数 3.1、strstr 3.2、strtok 4、错误信息报告函数

    2024年02月08日
    浏览(49)
  • C语言《超详细解析内存函数》

    memcpy指的是C使用的内存拷贝函数。 函数原型: (一)、参数: de:指向用于存储内容的目标数组,类型强制转换为void 指针。 sr:指向要复制的数据源,类型强制转换为void 指针 n:要被复制的字节数。 为什么要使用void* ,当传参的时候我们不知道传的是什么类型,而void就像

    2024年02月14日
    浏览(44)
  • 【C语言】字符函数与字符串函数以及内存函数 { 超详细攻略,一篇学会 }

    今日分享:字符、字符串函数和内存函数 内存函数 就是对内存进行操作的函数 字符串函数 就是对字符串进行操作的函数 字符函数 就是对字符进行操作的函数 str 前缀的函数是字符串函数,头文件string.h mem 前缀的函数是内存函数,头文件stdlib.h 字符分类函数包含在 ctype.h 头

    2024年03月18日
    浏览(59)
  • C语言内存函数介绍以及实现

    目录 前言 一:内存拷贝函数 (1)memcpy( )函数 (2)memove( )函数 二:内存比较函数 三:内存设置函数 本文介绍的函数的函数声明都在头文件string.h中。 函数声明:void* memcpy(void* dest,const void* src,size_t num) 作用:把一片内存空间的字节拷贝到另一片内存空间。 函数参数的意义: ①dest指

    2024年02月01日
    浏览(38)
  • 模拟strcpy库函数的实现(超详细)

    ⭐博客主页:️CS semi主页 ⭐欢迎关注:点赞收藏+留言 ⭐系列专栏:C语言初阶 ⭐代码仓库:C Advanced 家人们更新不易,你们的点赞和关注对我而言十分重要,友友们麻烦多多点赞+关注,你们的支持是我创作最大的动力,欢迎友友们私信提问,家人们不要忘记 点赞收藏+关

    2024年02月04日
    浏览(41)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包