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;
}
相关推荐
辞旧 lekkk29 分钟前
【Qt】信号和槽
linux·开发语言·数据库·qt·学习·mysql·萌新
2zcode1 小时前
运动模糊图像复原的MATLAB仿真与优化
开发语言·matlab
袁雅倩19971 小时前
当吸尘器、筋膜枪都用上Type-C,供电方案该怎么选?浅谈PD取电芯片ECP5702的应用
c语言·开发语言·支持向量机·动态规划·推荐算法·最小二乘法·图搜索算法
Aaswk2 小时前
Java Lambda 表达式与流处理
java·开发语言·python
万邦科技Lafite2 小时前
京东item_get接口实战案例:实时商品价格监控全流程解析
java·开发语言·数据库·python·开放api·淘宝开放平台
Cyber4K3 小时前
【Python专项】进阶语法-系统资源监控与数据采集(1)
开发语言·python·php
Le_ee4 小时前
ctfweb:php/php短标签/.haccess+图片马/XXE
开发语言·前端·php
yong99905 小时前
MATLAB读取高光谱图像
开发语言·matlab
2zcode5 小时前
基于MATLAB的肝病风险评估与分期分析系统设计与实现
开发语言·matlab
小小de风呀5 小时前
de风——【从零开始学C++】(五):内存管理
开发语言·c++