C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C语言内存函数

C语言内存函数的具体使用

作者:爱编程的小新☆

本文介绍了C语言中几个常用的内存函数,包括memcpy、memmove、memset、memcmp的使用方法及其模拟实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

上期我们学习了字符函数以及字符串函数,但是字符串函数仅仅只能对字符进行操作,那么这次我们来学习一下内存函数

在C语言中内存函数是一组用于内存操作的标准库函数,它们定义在 <string.h>头文件中,这些函数用于复制、设置、比较内存区域等,接下来我们来学习一下C语言中常用的内存函数。

1. memcpy 使⽤和模拟实现

memcpy与strcpy非常相似,但是strcpy只能对字符进行复制操作,而memcpy可以对任意类型的数据进行复制操作。

1.1 memcpy的使用

memcpy的使用:

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

运行结果:

可以这里的num参数为20, 表示从 arr1 复制20个字节的数据到 arr2中,因为这里复制的内容为整数,整形的大小占4个字节,所以arr2从arr1中复制了前5个数字(也就是20个字节的数据)

1.2 memcpy模拟实现

既然知道了memcpy函数是如何使用的,那么我们接下来探索一下memcpy是如何实现的

#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memcpy(void* dst, const void* src, size_t num)
{
	void* ret = dst;
	assert(dst);
	assert(src);
	
	while (num--) {
		*(char*)dst = *(char*)src;
		dst = (char*)dst + 1;
		src = (char*)src + 1;
	}
	return(ret);
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = { 0 };
	my_memcpy(arr2, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

运行结果:

我们可以看见模拟实现的my_memcpy函数与上面使用的memcpy函数的运行结果是一样的

从中memcpy的前两个形参使用的是void *类型来接收的,void *类型不能进行解引用和加减运算,所以在解引用和加减运算之前需要强制转换成char *类型进行操作

函数的返回值是void*类型,返回的是目标地址,所以在进行指针运算前,我们需要先创建一个指针(ret)存储目标地址,当复制操作完成后,返回目标地址

注意这里的dst和src是指针变量,所以在使用前用assert断言判断一下是否为NULL(空指针),并且因为src指针指向的数据是不能被修改的,所以这里用const进行修饰。

注意:memcpy只负责处理内存不重叠的情况,对于重叠内存拷贝使用memmove

2. memmove 使⽤和模拟实现

memmove函数的参数与memcpy函数是一样的

2.1 memmove的使用

#include<stdio.h>
#include<string.h>
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(arr1 + 2, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

运行结果:

那么为什么memmove函数能够处理内存重叠的情况呢?接下来我们来模拟实现一下memmove函数。

2.2 memmove模拟实现

#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memmove(void* dst, const void* src, size_t count)
{
	void* ret = dst;
	if (dst <= src || (char*)dst >= ((char*)src + count))
	{
		
		while (count--) 
		{
			*(char*)dst = *(char*)src;
			dst = (char*)dst + 1;
			src = (char*)src + 1;
		}
	}
	else 
	{
		dst = (char*)dst + count - 1;
		src = (char*)src + count - 1;
		while (count--) 
		{
			*(char*)dst = *(char*)src;
			dst = (char*)dst - 1;
			src = (char*)src - 1;
		}
	}
	return(ret);
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr1 + 2, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

memmove的模拟实现与memcpy是相似的,但是这里需要分为两种情况讨论:

1. 目标地址>源内存地址

如果目标地址 > 源内存地址,那么我们就需要将数据从后向前进行拷贝,如果从前向后进行拷贝就会发生下面的现象

当我们从后面向前拷贝就不会出现这种现象:

2. 目标地址<源内存地址

如果目标地址 < 源内存地址,那么我们就需要将数据从前向后进行拷贝

3. 目标地址=源内存地址

当目标地址=源内存地址时,既可以使用从前向后的方式拷贝也可以使用从后向前的方式拷贝。

3. memset 函数的使⽤

memset是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容。

memset的使用:

int main()
{
	char str[] = "hello world";
	memset(str, 'x', 6);
	printf(str);
	return 0;
}

运行结果:

memset函数将str数组中的前6个字节的数据更改成了 ’x‘  

4.memcmp 函数的使用

memcmp是用于比较两块内存
将指针 1 所指内存块的前 num 个字节与指针 2 所指内存块的前num个字节进行比较,如果它们完全匹配,则返回零,否则返回一个不等于零的值,表示哪个更大。

返回值如下:

 memcmp函数的使用:

这里我们比较的是两个整形数组前4个数据的大小, 一个整形的大小为4个字节,所以比较的是16个字节数据的大小,arr前16个字节的数据<arr2前16个字节的数据,所以返回值为-1。

结语

那么以上就是C语言中常用的内存函数,学完内存函数后,对于复制、设置、比较等操作就不仅仅只局限在字符中了,也可以对任意类型的数据进行复制、设置、比较等操作。到此这篇关于C语言内存函数的具体使用的文章就介绍到这了,更多相关C语言内存函数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文