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;
}
相关推荐
秃头佛爷6 分钟前
Python学习大纲总结及注意事项
开发语言·python·学习
待磨的钝刨7 分钟前
【格式化查看JSON文件】coco的json文件内容都在一行如何按照json格式查看
开发语言·javascript·json
XiaoLeisj2 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
励志成为嵌入式工程师3 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉4 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer4 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq4 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
记录成长java5 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
前端青山5 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
hikktn5 小时前
如何在 Rust 中实现内存安全:与 C/C++ 的对比分析
c语言·安全·rust