【C语言】memcpy,memmove,memcmp,memset函数详解

memcpy,memmove,memcmp,memset函数详解

memcpy函数

#include<string.h>

一、 memcpy函数的定义:

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

与strncmp区别是:参数方面:1.memcpy可以拷贝任意类型数据;2.num是字节数

二、memcpy函数的功能:

== 复制内存块==

将字节数的值从源指向的位置直接复制到目标指向的内存块。

源指针和目标指针指向的对象的基础类型与此函数无关;结果是数据的二进制副本。

该函数不检查源中的任何终止空字符 - 它总是准确地复制字节数。

为避免溢出,目标和源参数指向的数组大小应至少为字节数,并且不应重叠(对于重叠的内存块,memmove 是一种更安全的方法)

三、memcpy函数模拟

c 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest, void* src, size_t num)
{
	void* ret = dest;
	assert(dest);
	while (num--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;

}
int main()
{
	int arr1[] = { 0,1,2,3,4,5,6,7,8,9 };
	int arr2[20] = { 0 };
	my_memcpy(arr2, arr1, 40);
	int i = 0;
	for (i = 0; i < 20; i++)
	{
		printf("%d\n", arr2[i]);
	}
	return 0;
}
 

memcpy注意事项

1 .函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
2 .这个函数在遇到 '\0' 的时候并不会停下来
3.如果source和destination有任何的重叠 ,复制的结果都是未定义的。

原因也很简单:如下代码

c 复制代码
int arr1[] = { 0,1,2,3,4,5,6,7,8,9 };
	my_memcpy(arr1+2, arr1, 40);

给自己复制时,肯定时一位一位复制,把arr1[0]复制到arr+2(arr[2])位置时,arr1【2】的数值被覆盖为0,那么当我们继续复制时再取出arr[2]的值就是你之前已经复制过的了0,而不是原本的数值2,就不再是你想要复制的数据了。
4.

c 复制代码
my_memcpy(arr2, arr1, 9);

这里我只复制前9个字节,可以发现打印出来了0,1,2.这是为什那么呢?

原因是:我们的vs编译器是小端存储(即,数据低位存到内存的高地址),

1,2,3在内存中的二进制存储为:
01 00 00 00|02 00 00 00|03 00 00 00 【一个00也就是一字节】

存储就9字节,正好把3 的关键位给复制进去了。

memmove函数

#include<string.h>

一、memmove函数简介

c 复制代码
void * memmove ( void * destination, const void * source, size_t num );

参数与memcpy一样

与memcpy函数区别是,它通常被用在源空间和目标空间出现重叠时

二、memmove函数的模拟

1.两种情况

memomove复制时,有两种情况

1.dest地址<src地址: 从前到后(左到右)

2.dest地址>src地址: 从后到前(右到左)

2模拟实现

c 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest, void* src, size_t num)
{
	void* ret = dest;//保存初始位置地址
	assert(dest);//确保dest不为空
	if (dest < src)//分两种情况
	{
		while (num--)//情况一,从左到右复制
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		while (num--)情况二:从右到左复制
		{
			*((char*)dest + num) = *((char*)src + num);
			//先强制转换成char型,再加上num个字节。
			//就是指向src,dest的末尾元素
		}
	}
	return ret;

}
int main()
{
	int arr1[] = { 0,1,2,3,4,5,6,7,8,9 };
	my_memcpy(arr1+5, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d\n", arr1[i]);
	}
	return 0;
}

memcmp函数

#include<string.h>

memecmp函数介绍

定义

c 复制代码
int memcmp ( const void * ptr1, const void * ptr2, size_t num );

参数:ptr1和ptr2都指向内存块的指针。

num:要比较的字节数
返回值:

返回一个整数值,该值指示内存块内容之间的关系:

返回值 表明
小于0 ptr2大(指向的第一个不相等字符块)
0 两个内存块的内容相等
大于0 ptr1大

功能

将 ptr1 指向的内存块的前 num 字节数与 ptr2 指向的第一个字节数进行比较,

如果它们都匹配,则返回零,

如果不匹配,则返回一个不同于零的值,表示哪个值更大。 请注意,与 strcmp 不同,该函数在找到空字符后不会停止比较。

memset函数

#include<string.h>

memset函数介绍

c 复制代码
void * memset ( void * ptr, int value, size_t num );

参数 : ptr;指向要填充的内存块的指针。

value:要设置的值。该值作为 int 传递,但该函数使用此值的无符号 char 转换填充内存块。

num:字节数
返回值:修改后的ptr

memset功能

memset使用

案例一:

c 复制代码
#include<string.h>
int main()
{
	int arr[10] = { 0 };
	memset(arr, 1, 20);
	return 0;
 }

它是将每一个字节都赋值成1;

案例二:

c 复制代码
#include<string.h>
int main()
{
	char arr[10] = { "hellloni"};
	memset(arr, 'x', 5);
	printf("%s", arr);
	return 0;
 }
 
相关推荐
waicsdn_haha11 分钟前
Java/JDK下载、安装及环境配置超详细教程【Windows10、macOS和Linux图文详解】
java·运维·服务器·开发语言·windows·后端·jdk
嵌入式科普12 分钟前
十三、从0开始卷出一个新项目之瑞萨RZN2L串口DMA接收不定长
c语言·stm32·瑞萨·e2studio·rzn2l
_WndProc13 分钟前
C++ 日志输出
开发语言·c++·算法
qq_4335545422 分钟前
C++ 面向对象编程:+号运算符重载,左移运算符重载
开发语言·c++
数据小爬虫@41 分钟前
如何高效利用Python爬虫按关键字搜索苏宁商品
开发语言·爬虫·python
ZJ_.43 分钟前
WPSJS:让 WPS 办公与 JavaScript 完美联动
开发语言·前端·javascript·vscode·ecmascript·wps
Narutolxy1 小时前
深入探讨 Go 中的高级表单验证与翻译:Gin 与 Validator 的实践之道20241223
开发语言·golang·gin
Hello.Reader1 小时前
全面解析 Golang Gin 框架
开发语言·golang·gin
禁默1 小时前
深入浅出:AWT的基本组件及其应用
java·开发语言·界面编程
Code哈哈笑1 小时前
【Java 学习】深度剖析Java多态:从向上转型到向下转型,解锁动态绑定的奥秘,让代码更优雅灵活
java·开发语言·学习