C语言内存函数

目录

一.memcpy函数

函数介绍

memcpy函数的模拟实现

二.memmove函数

函数介绍

memmove函数的模拟实现

三.memset函数

函数介绍

四.memcmp函数

函数介绍

返回值


一.memcpy函数

cpp 复制代码
void* memcpy(void* destination, const void* source, size_t num);

函数介绍

strcpy是复制字符串,而memcpy就是复制内存块。

memcpy会从source所指向的空间复制num个字节(不是元素个数而是字节)到destination所指向的空间。

source和destination所指向的的对象的类型是不重要的,这个函数仅仅是对二进制数据的拷贝。

这个函数与strcpy不同,它是不会管'\0'的,总是精准的复制num个字节。

为了避免越界。source和destination所指向的空间的大小至少应该是num个字节。

如果source和destination所指向的空间有所重叠,就不应该使用memcpy而是memmove;

  1. destination就是目标位置的指针。
  2. source就是指向源位置的指针。
  3. 就是需要复制的字节个数。(size_t是一种无符号整形)

为了针对任意类型的数据进行复制,所以参数的类型是void*类型的

memcpy函数的模拟实现

cpp 复制代码
void* my_memcpy(void* destination, const void* source, size_t num)
{
    void * ret = destination;
	while (num--)
	{
		*(char*)destination = *(char*)source;
		destination = (char*)destination + 1;
		source = (char*)source + 1;
	}
    return ret;
}
int main()
{
	char str1[20] = "xxxxx world";
	char* str2 = "hello";
	printf("%s\n", str1);
	my_memcpy(str1, str2, 5);
	printf("%s", str1);
	return 0;
}

void*类型的指针是不能进行解引用的操作的,所以我们需要对其进行类型转换。之所以转化为char*类型的指针,那是因为1个字节可以确保任意字节数的内存块都可以复制,如果需要9个字节,使用int*类型就不行,因为int*的指针解引用得到的是4个字节,无法凑齐9.

注意:void*不是void,void*是有返回值的。

二.memmove函数

函数介绍

这个函数与memmmove函数几乎没有区别,但是memmove可以用于空间重叠的情况。

假设这这里的dest和source有一部分重叠了 。复制六个整形的话,5和六就重叠在了一起,那么这种情况下如何复制呢?

我们将source的数据依次向前复制,当5要被覆盖的时候,我们已经要用9了,这对复制并不会造成影响。

可换一种情况:

这时候我们就不能先将1复制给dest,因为我们再拷贝5的时候,5已经被覆盖了,我们想要的效果就没有达到。我们我们可以倒着复制先将6复制到10的位置上。

memmove函数的模拟实现

cpp 复制代码
void* my_memmove(void* destination, const void* source, size_t num)
{
	void* ret = destination;
	if (destination < source)
	{
		while (num--)
		{
			*(char*)destination = *(char*)source;
			((char*)destination)++;
			((char*)source)++;
		}
	}
	else {
		while (num--)
		{
			*((char*)destination+num) = *((char*)source+num);
		}
	}
	return ret;
}
int main()
{
	char str1[20] = "xxxxx world";
	char* str2 = "hello";
	printf("%s\n", str1);
	my_memmove(str1, str2, 5);
	printf("%s", str1);
	return 0;
}

三.memset函数

函数介绍

这个函数是用于设置内存的,设置ptr所指向的内存块的前num个字节为value值。

例子:

cpp 复制代码
int main()
{
	int arr[5] = { 1,2,3,4,5 };
	memset(arr, 0, 20);//以字节为单位设置的
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

这个函数的模拟实现读者有兴趣,可以参考前面讲解的函数自行完成。

四.memcmp函数

函数介绍

比较ptr1和ptr2所指向的一个空间的前num个字节的内存,如果完全相等则返回0,反之则返回一个非0的数字。

这个函数与strcmp函数不同,它停止比较只取决于num,与'\0'字符无关。

返回值

这个返回值表明了这两个内存的关系

如果ptr1的值小于ptr2,就返回一个复制,反之返回值一个正数。这个值是前num个字符的ASCII值 之和计算的。

cpp 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
	char buffer1[] = "DWgaOtP12df0";
	char buffer2[] = "DWGAOTP12DF0";

	int n;

	n = memcmp(buffer1, buffer2, sizeof(buffer1));

	if (n > 0) printf("'%s' is greater than '%s'.\n", buffer1, buffer2);
	else if (n < 0) printf("'%s' is less than '%s'.\n", buffer1, buffer2);
	else printf("'%s' is the same as '%s'.\n", buffer1, buffer2);

	return 0;
}
相关推荐
Logic1016 分钟前
C语言/数据结构动态规划题解:字符串变回文的最少操作次数——最长回文子序列(LPS)
c语言·数据结构·算法·动态规划·时间复杂度·回文串·最长回文子序列
薛之谦_9 分钟前
JAVA 多线程编程:从基础原理到实战应用
java·开发语言
LMT_Lanmantech10 分钟前
Creo许可降本增效:不增购,也能让现有许可发挥更大价值
java·大数据·开发语言
wuminyu28 分钟前
ZGC染色指针在虚拟线程stackChunkOop上的并发屏障全景分析
java·linux·c语言·jvm·c++
蜗牛互联网40 分钟前
Python Agent 工具调用:审批令牌、参数白名单和累计预算
java·开发语言·人工智能·windows·后端·python
Logic1011 小时前
C语言/数据结构组合数学题解:数字好排列计数——质数倍数分类与阶乘取模
c语言·数据结构·算法·组合数学·时间复杂度·排列·取模运算
承渊政道1 小时前
【Python编程—从入门到实践】(让程序记得、恢复并解释失败:Python 文件、异常与JSON系统教程)
开发语言·python·pycharm·json·异常处理
一水鉴天1 小时前
声调韵的序:从古汉语音韵到系统科学语言的场效应推演 20261013(千问)
开发语言·人工智能
郭庆汝1 小时前
(六)MCP+A2A之——Playwright与BrowserUse:让AI学会像人类一样使用浏览器
开发语言·python
涉密IT资质笔记2 小时前
涉密资质投入产出分析模型:时间成本、四块成本构成与 ROI 决策框架
java·开发语言·算法