C进阶:内存操作函数

内存操作函数

memcpy

头文件:string.h

基本用途:进行不相关(不重叠的内存)拷贝。

函数原型:void* memcpy(void* destination,//指向目标数据的指针

const void* source,//指向被拷贝数据的指针

size_t num);//拷贝的数量(单位:字节)

注:

1.基本原理:从source的位置开始向后复制num个字节的数据到destnation的内存位置。

2.这个函数与strcpy不同,它遇见'\0'的时候并不会停下来。

3.如果source和destnation有任何的重叠,复制的结果都是未定义的。

4.void* 之前讲过,为了保证泛用性,使用void*接收任意类型的数据。

使用举例:

cpp 复制代码
#include <stdio.h>
#include <string.h>

struct {
	char name[40];
	int age;
}person, person_copy;

int main()
{
	char myname[] = "Pierre de Fermat";
	
	memcpy(person.name, myname, strlen(myname) + 1);
	person.age = 46;

	memcpy(&person_copy, &person, sizeof(person));
	printf("person_copy: %s , %d\n", person_copy.name, person_copy.age);
	return 0;
}

这是将字符串和结构体成员变量拷贝到另一个结构体的举例。

为了更好的理解这一函数,下面我们来模拟实现一下它。

cpp 复制代码
void* my_memcpy(void* dest, const void* src, size_t num)
{
	//断言,防止dest或者src是空指针,如果是空指针则会报错
	assert(dest && src);
	//保存起始地址
	void* ret = dest;
	while (num--)
	{
		//一次用最小单位(字节)移动,保证泛用性
		*(char*)dest = *(char*)src;
		//注:强制类型转换只是临时的,后面+1操作时已不存在
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	//返回目标空间的起始地址
	return ret;
}

memmove

头文件:string.h

基本用途:重叠内存块的拷贝

函数原型:void* memove(void* destnation, const void* source, size_t num)

注:

1.和memcpy的区别就是memove函数处理的源内存块和目标内存块可以重叠。

2.如果原空间和目标空间出现重叠,就得使用memmove函数处理。

使用举例:

cpp 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
	char str[] = "memmove can be very useful.....................";
	//将字符串中从第15个元素的位置向后数共11个字符挪到从第20个字符开始向后数第11个元素
	memmove(str + 20, str + 15, 11);
	puts(str);
	return 0;
}

该函数的模拟实现:

cpp 复制代码
#include <stdio.h>
#include <string.h>
#include <assert.h>

void* my_memmove(void* dest, const void* src, size_t num)
{
	assert(dest && src);
	//当目标位置地址小于源内存块数据地址时,采用从前向后拷贝的方式
	if (dest < src)
	{
		//根据字节数量一个一个移动内存单元
		while (num--)
		{
			*(char*)dest = *(char*)src;
			//向后移动一位
			dest = (char*)dest + 1;
			src = (char*)dest + 1;
		}
	}
	//当目标为指针大于源内存块数据地址时,采用从后向前的拷贝方式
	else if (dest > src)
	{
		//将dest和src指针定位到各自最后的内存地址处
		dest = (char*)dest + num - 1;
		src = (char*)src + num - 1;
		//根据字节数量一个一个移动内存单元
		while (num--)
		{
			*(char*)dest = *(char*)src;
			//向前移动一位
			dest = (char*)dest - 1;
			src = (char*)src - 1;
		}
	}
}

memcmp

头文件:stdio.h

基本用途:顾名思义,与strcmp函数类似,这个函数是比较内存数据大小的(逐字节)。

函数原型:int memcmp(const void* ptr1, const void* ptr2, size_t num);

注:

1.比较从ptr1和ptr2开始的num个字节

2.与strcmp返回值类似,仍是第一个指针内容大于第二个指针的内容,返回大于零的数字,第一个指针内容小于第二个指针的内容,返回小于零的数字,相等,返回零。

基本举例:

cpp 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
	char buffer1[] = "axxxxxxxxxxx";
	char buffer2[] = "bbbbbbbbbbbb";

	int n;
	n = memcmp(buffer1, buffer2, sizeof(buffer1));
	printf("%d", n);
	return 0;
}

结果:

这期的博客就分享到这里啦,谢谢各位啦!!!

相关推荐
方安乐4 小时前
python之向量、向量和、向量点积
开发语言·python·numpy
三品吉他手会点灯5 小时前
C语言学习笔记 - 20.C编程预备计算机专业知识 - 变量为什么必须的初始化【重点】
c语言·笔记·学习
小小小米粒5 小时前
Collection单列集合、Map(Key - Value)双列集合,多继承实现。
java·开发语言·windows
czhc11400756636 小时前
C# 428 线程、异步
开发语言·c#
:1216 小时前
java基础
java·开发语言
SilentSamsara7 小时前
Python 环境搭建完整指南:从下载安装到运行第一个程序
开发语言·python
小短腿的代码世界7 小时前
Qt文件系统与IO深度解析:从QFile到异步文件操作
开发语言·qt
JasmineX-18 小时前
数据结构(笔记)——双向链表
c语言·数据结构·笔记·链表
harder3219 小时前
RMP模式的创新突破
开发语言·学习·ios·swift·策略模式
jinanwuhuaguo9 小时前
OpenClaw工程解剖——RAG、向量织构与“记忆宫殿”的索引拓扑学(第十三篇)
android·开发语言·人工智能·kotlin·拓扑学·openclaw