C语言中内存操作函数的介绍与模拟

本篇文章将介绍C语言中的内存函数的用法以及模拟实现,大家快搬好小板凳来听讲啦~


要介绍的内存操作函数有以下四种:

  1. memcpy
  2. memmove
  3. memset
  4. memcmp

1、memcpy

· 这个函数的功能是在缓存区之间复制字符(此字符不仅局限于char型的数据),怎么来理解呢?

· 通俗地讲,就是将缓存区的一部分数据复制到另一块地方去,跟字符串函数strcpy很想,只不过,memcpy的功能更加强大,可以对不同类型的数据进行操作。

· 话不多说,上操作!

#include<stdio.h>
#include<memory.h>
//#include<string.h>
//想要使用memcpy需要包含以上两个头文件的至少一个

int main()
{
    //使用内存函数
    int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int arr2[] = {12, 23, 34, 45, 56};
    memcpy(arr1, arr2, 20);//将arr2里面前20个字节的内容复制到arr1中

    //打印数组arr1
    int i = 0;
    int sz = sizeof(arr1) / sizeof(arr1[0]);
    for (i = 0; i < sz; i++)
    {
        printf("%d ", arr1[i]);
    }

    return 0;
}

以上是使用内存函数的实例代码,运行结果如下图

· 先解释一下memcpy的使用,

void *memcpy( void *dest, const void *src, size_t count );//memcpy的定义

· 传入两个数组的地址,定义的是void*类型,这就是为什么memcpy可以处理多种类型数据的原因,只要在函数内部进行强制转换就ok,count是要进行操作的字节数,因为int是4个字节,所有20就是操作5个int元素。

· 知道了函数的使用和实现的功能,接下来咱就来自己模拟一下

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

void* my_memcpy(void* dest, void* src, size_t count)
{
	assert(dest && src);//断言dest和src不是空指针,因为空指针解引用是非法的
	void* ret = dest;//函数返回的是目标数组的首元素地址,因为接下来dest会发生变化,所有提前定义变量存储dest的地址
	while (count--)
	{
		*((char*)dest) = *((char*)src);//强制转换为char*类型数据,进行一个字节一个字节的修改
		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[] = { 12, 23, 34, 45, 56 };
	my_memcpy(arr1, arr2, 20);

	int i = 0;
	int sz = sizeof(arr1) / sizeof(arr1[0]);
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

·模拟的想法是很简单的,只要进行一个字节一个字节的访问,然后依次赋值就好啦~

2、memmove

· memmove函数实际上是对memcpy函数的进一步优化,使得函数操作的对象可以是同一个数组

上操作!

#include<stdio.h>
#include<string.h>//使用memmove需要引用的头文件

int main()
{
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	memmove(arr + 3, arr, 20);

	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

· 以上是使用内存函数的实例代码,运行结果如下图

· memmove的参数设置和memcpy相同,只是内部函数实现有所不同

· 接下来我们自己上手实现以下,来发现memmove与memcpy有什么不一样~

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

void* my_memmove(void* dest, void* src, size_t count)
{
	assert(dest && src);
	void* ret = dest;
	if (dest < src)//如果dest的地址低于src,数组从前往后进行赋值不会造成数据的提前覆盖
	{
		while (count--)
		{
			*((char*)dest) = *((char*)src);
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		while (count--)//如果dest的地址高于src,数组从后往前进行赋值不会造成数据的提前覆盖,用count来控制数组从最后往前一次赋值,dest和src就不用进行变化了
		{
			*((char*)dest + count) = *((char*)src + count);
		}
	}
	return ret;
}
//思想依然是一个字节一个字节的访问,只不过对dest和src的地址高低进行了判断

int main()
{
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	my_memmove(arr + 3, arr, 20);

	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;

}

 3、memset

·这个函数的功能是将缓冲区的数据设定为指定字符

· 干巴巴的文字说明看着头痛,直接上操作!

#include <stdio.h>
#include <memory.h>

int main()
{
	char buffer[] = "This is a test of the memset function";

	printf("Before: %s\n", buffer);
	memset(buffer, '*', 4);
	printf("After:  %s\n", buffer);
	return 0;
}

· 以上是使用内存函数的实例代码,运行结果如下图

·解释一下函数的使用

void *memset( void *dest, int c, size_t count );

 · 传入要修改的数组的首地址,要修改成的数据(传入char的话就是传入它的ANSII码),操作的字节数,还是很好理解的

· 接下来,咱就继续上手模拟

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

void* my_memset(void* dest, int c, size_t count)
{
	assert(dest);
	void* ret = dest;
	while (count--)
	{
		*((char*)dest) = c;
		dest = (char*)dest + 1;
	}
	return ret;
}

int main()
{
	char buffer[] = "This is a test of the memset function";

	printf("Before: %s\n", buffer);
	my_memset(buffer, '*', 4);
	printf("After:  %s\n", buffer);
	return 0;
}

· 这个函数的模拟相较于上两个函数更加简单~

4、memcmp

· 这个函数跟strcmp就非常相似了,不过比较的数据类型范围更广

· 上操作~

#include <string.h>
#include <stdio.h>

int main()
{
	int arr1[10] = { 1,2,3,4,5,5,6,7,8,9 };
	int arr2[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int ret = memcmp(arr1, arr2, 40);
	if (ret > 0)
	{
		printf("arr1数组里的数大于arr2数组里的数\n");
	}
	else
		if(ret==0)
		{
			printf("arr1数组里的数等于arr2数组里的数\n");
		}
		else
		{
			printf("arr1数组里的数小于arr2数组里的数\n");
		}
	return 0;
}

· 以上是使用内存函数的实例代码,运行结果如下图

 · 此函数的定义为

int memcmp( const void *buf1, const void *buf2, size_t count );

· 传入两个相比较数组的首元素地址,再传入要比较的字节数,然后返回一个int类型的数据

· 模拟走起!

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

int my_memcmp(const void* buf1, const void* buf2, size_t count)
{
	assert(buf1 && buf2);
	while ((*(char*)buf1 == *(char*)buf2) && count)
	{
		count--;
		buf1 = (char*)buf1 + 1;
		buf2 = (char*)buf2 + 1;
	}
	return (*(char*)buf1 - *(char*)buf2);
}

int main()
{
	int arr1[10] = { 1,2,3,4,5,5,6,7,8,9 };
	int arr2[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int ret = my_memcmp(arr1, arr2, 40);
	if (ret > 0)
	{
		printf("arr1数组里的数大于arr2数组里的数\n");
	}
	else
		if (ret == 0)
		{
			printf("arr1数组里的数等于arr2数组里的数\n");
		}
		else
		{
			printf("arr1数组里的数小于arr2数组里的数\n");
		}
	return 0;
}

· 4个内存函数的介绍与模拟就结束了,就我个人总结来讲,内存操作函数都是进行一个字节一个字节的访问,只要掌握了字节访问的方法问题就不大了~

· 欢迎各位uu的指正和建议~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值