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;
}
相关推荐
isyangli_blog4 小时前
OpenDayLight (Carbon 版本) 启动与组件安装
开发语言·php
vb2008114 小时前
FastAPI APIRouter
开发语言·python
Benszen4 小时前
KVM虚拟化解决方案
开发语言·perl
会编程的土豆4 小时前
Go 语言反射(Reflection)详解
开发语言·后端·golang
東雪木4 小时前
多线程与并发编程 专属复习笔记
java·开发语言·笔记·java面试
杨充4 小时前
1.3 浮点型数据设计灵魂
开发语言·python·算法
噜噜噜阿鲁~4 小时前
python学习笔记 | 11.3、面向对象高级编程-多重继承
java·开发语言
basketball6165 小时前
Go 语言从入门到进阶:4. 数组和MAP使用方法总结
开发语言·后端·golang
春生野草5 小时前
反射、Tomcat执行
java·开发语言
雪的季节6 小时前
企业级 Qt 全功能项目
开发语言·数据库·qt