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;
}
相关推荐
晓蛋1 天前
c语言指的是什么意思
c语言·编译器·编程开发·集成开发环境·程序实例
小羊没烦恼!1 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
傲世仙尊1 天前
目录即文件-Ext文件系统收尾篇
linux·c语言
牵猫散步的鱼儿1 天前
重载、重写(覆盖)、重定义区别
c语言
伞伞悦读1 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
phltxy1 天前
C 语言指针:从内存地址到灵活的数据访问
c语言
C语言小火车1 天前
C/C++ 为什么需要编译器?
开发语言·c++
phltxy1 天前
C 语言中的数据存储:从类型到二进制位
c语言
霍霍的袁1 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
孙启超1 天前
【AI开发之Rust】第 11 课:智能指针与内部可变性
开发语言·后端·rust