C/C++相关概念和易错知识点(7)(memcpy和memmove、文件函数)

标准仿C语言 memset、memcpy、memmove函数(含C#版) 标准仿C语言  memset、memcpy、memmove函数       前段时间,移植了C的网络加解密算法到C#,其中遇到很多问题,核心问题大多都是字节拷贝问题,今天有时间整理了一下相关的API,废话不多说直接贴源码:       (值得注意的是memmove函数,支持数据重叠,详情参照点击打开链接) 二> C#版 / 标准仿C memcpy函数 unsafe public voi 阅读详情

1.memcpy

标准格式:

void * memcpy ( void * destination, const void * source, size_t num );

(1)注意memcpy是无脑复制粘贴的,就算越界访问

(2)复制粘贴的区域不要有重复的,否则会出现数据错误,一般情况下建议使用memmove,你大可以将memcpy想象成低级的memmove

下面是memcpy的模拟实现:



#include <stdio.h>

#include <assert.h>

void* my_memcpy(void* arr2, const void* arr1, size_t num)
{
	assert(arr1 && arr2);

	void* ret = arr2;

	while (num--)
	{
		*((char*)arr2)++ = *((char*)arr1)++;
	}

	return ret;
}


int main()
{
	char arr1[] = "Hello,world!";

	char arr2[20] = { 0 };

	printf("%s\n",(char*)my_memcpy(arr2, arr1, 11));


	return 0;
}

2.memmove 

标准格式:void * memmove ( void * destination, const void * source, size_t num );

(1)在一般情况下,可以将memmove视作更为强大的memcpy,memmove可以复制重合的内容,所以一般情况下避免使用memcpy

相关代码的实现如下:



#include <stdio.h>

#include <assert.h>


void* my_memmove(void* arr2, void* arr1, size_t num)
{
	assert(arr1 && arr2);

	int i = 0;


	if (arr2 >= arr1)//源字符串的地址较低,从后侧开始
	{
		for (i = 1; i <= num; i++)
		{
			*((char*)arr2 + num - i) = *((char*)arr1 + num - i);

		}
		
	}
	else
	{
		for (i = 0; i < num; i++)
		{
			*((char*)arr2 + i) = *((char*)arr1 + i);
		}

	}

	return arr2;

}



int main()
{

	char arr[20] = "Hello,world!";

	printf((char*)my_memmove(arr + 3, arr, 5));

	return 0;
}

3.memset

标准格式:void* memset(void* ptr, int value, size_t num);

实现代码如下:


#include <stdio.h>

#include <assert.h>

void* my_memset(void* arr, int i, size_t num)
{
	assert(arr);

	int m = 0;

	for (m = 0; m < num; m++)
	{
		*((char*)arr + m) = i;

	}

	return arr;

}


int main()
{

	char arr[20] = "Hello,world!";

	printf((char*)my_memset(arr, '-', 5));


	return 0;
}

注意这里的形参虽然接受的是个整形,但字符本质上也是以ASCII码的形式存储的,所以这里能够传入字符,且在赋值时会自动进行类型转换。

4.char与unsigned char

(1)char

由于char 只有8个bit位的存储空间,所以它最多能表示256个数字(包含0),但在signed char中,由于存在原反补的存储规则,导致01111111是最大的正数,对应过来是127,如果再加,就会是10000000,除符号位按位取反+1得到1 00000000,截断后本应是0,但这和0000000冲突了,也就是说0会出现两次,因此规定在这种情况下,127+1 = -128。再往后+1得10000001,除符号位按位取反得11111110,+1得11111111,对应的就是-127,以此类推。

这样会出现一些案例,如:


#include <stdio.h>

#include <string.h>

int main()
{
	char a = 127;

	char arr[1000] = { 0 };
	
	int i = 0;

	for (i = 0; i < 1000; i++)
	{
		arr[i] = a + i;
	}

	printf("%zu\n", strlen(arr));

	return 0;
}

最终输出的结果是

这里实际装进数组的对应字符的ASCII码值是127,-128,-127......-1,0,.....

实际识别到0(也就是\0)就停止了,因此用strlen识别出的大小是129

(2)unsigned char

在这里,符号位的概念不复存在,8个bit位都被视作数值位,因此最高可以表255,再+1就会循环。

5.浮点数存储的注意事项:

注意存储的顺序分别是:浮点数的符号(0为正,1为负),指数位(无符号型),有效数字

(1)指数位:注意这是以二进制存储,底数为2,指数位会加上一个中间值来保证不会出现负数指数的情况,因此要主动换算一次才能得到真实的指数位

(2)有效数字,一般情况下,科学计数法的有效数字都是1.xxxx形式,所以自动忽略1,回算时再主动添加上去,但如果指数位全为0,回算时加0,这代表无穷小,也就是0。如果指数位全为1,表正负无穷大

(3)对于32位浮点数,1bit给符号位,8bit给指数位(中间值127),其余23bit给有效数字

对于64位浮点数,1bit给符号位,11bit给符号位(中间值1023),其余52bit给有效数字

(4)一般自己书写时的逻辑是符号位,有效数字,指数位。但存储顺序不一样,这点要注意!

6.结构体,联合体,枚举变量,柔性数组的用法

这四个知识点比较简单,这里用作复习

下面看一段代码:




#include <stdio.h>

#include <stdlib.h>

#include <assert.h>


enum sex
{
	male,

	female,

	secret
};

struct S
{
	union m
	{
		int i;

		char name[20];

		char id[30];

	};

	enum sex j;

	int arr[0];

};

int main()
{

	int m = 0;

	printf("结构体的大小是%zu\n", sizeof(struct S));

	printf("联合体的大小%zu\n", sizeof(union m));

	struct S* s = (struct S*)malloc(sizeof(struct S) + sizeof(int) * 10);

	assert(s);

	s->i = 20;

	s->j = male;

	for (m = 0; m < 10; m++)
	{
		s->arr[m] = m;
	}

	for (m = 0; m < 10; m++)
	{
		printf("%d ", s->arr[m]);
	}


	free(s);

	s = NULL;


	return 0;
}

注意事项:(1)结构体可以和union等嵌套使用

(2)enum的成员列表中的成员之间用','(逗号)隔开

(3)malloc要和free和NULL联合使用,避免内存泄漏,野指针的情况发生

(4)s->arr这种操作在语法上不被允许,只允许对arr[0]等逐一修改,因此这段代码避免了这种写法

(5)union的大小必须满足是最大对齐数的整数倍,即union也存在对齐现象

(6)柔性数组必须在结构体的最后一个元素,和内存开辟函数结合使用,结构体实质上是在堆上创建空间的

7.流

流是将程序和输入输出设备联系起来的媒介,输入设备比如键盘、数据文件(包含文本文件和二进制文件)等,输出设备比如控制台、数据文件等。

我们平时使用的scanf就是将键盘上的内容输入到流里,再通过流(FILE* stdin)读到程序中

printf就是将程序中的内容写到流(FILE* stdout)里,再通过相应操作打印到控制台的屏幕上。

我们不需要关注流与输入输出设备之间的联系方式,只需关注我们要从流中得到什么信息和输入什么信息到流中。

C语言在程序运行时会默认打开stdin,stdout,stderr,我们日常所用的printf,scanf,gets等都是我们和流进行交互,只是C语言底层帮我们实现了很多东西,所以我们之前没有感知。

流是一种文件指针,文件指针实质上是一种结构体指针的重命名,它们指向的结构体包含了对应输入或输出设备的信息,比如stdin这个结构体就包含了键盘的一些信息,也包含了键盘和程序进行沟通的信息等。

流可以以指针的形式对对应结构体进行操作,从而实现对输入输出设备的操作。这部分不需要关心,这是在C语言底层实现的。

这个概念的理解帮助我们对文件操作和程序运行逻辑的理解。

8.fprintf,sprintf和fscanf,sscanf的理解和使用

(1)fprintf 和 fscanf

这里就是必须要在理解流的概念之后才会理解这个函数。

fprintf,fscanf只有第一次参数多了一个FILE*的变量,也叫流的种类,这两个函数适用于任何流,同样的还有fgets,fputs,fgetc,fputc

fscanf会根据不同的流将对应设备中的数据读到程序中,这里stdin对应的设备是键盘

fprintf会根据不同的流将数据写到流对应的设备中,在这里stdout对应的设备是控制台的屏幕

(2)sprintf 和 sscanf

用通俗的话来说,sprintf是将格式化的数据打印成字符串,sscanf是将字符串中的数据提出来,变成格式化的数据,这样有助于理解

sprintf必须加上“打印”成字符串后保存该字符串的首元素地址

sscanf必须加上“提取”格式化数据所对应字符串的首元素地址

下面来看一组代码加强理解:




#include <stdio.h>

#include <stdlib.h>


enum sex
{
	male,

	female,

	secret,

};


struct Stu
{
	char name[20];

	int age;

	enum sex s;

}s1;


int main()
{

	char arr[100] = { 0 };

	char inf[30] = "Lihua 18 male";

	sscanf(inf, "%s %d %d", s1.name, &(s1.age), &(s1.s));

	fprintf(stdout, "%s %d %d\n", s1.name, s1.age, s1.s);

	sprintf(arr, "%s %d %d", s1.name, s1.age, s1.s);

	fprintf(stdout, arr);

	return 0;
}

运行的结果是

这里的逻辑就是将一串字符提取成格式化数据后,打印该格式化数据;再从格式化数据打印到另一个字符串中,最后再打印这个字符串。

值得注意的是,enum赋值时必须按照其成员的名字命名,而不能是数字,虽然在这里0代表male,但赋值的时候必须以male的输入方式赋值。

9.文件操作中常见的函数

这几个函数在文件操作里面比较常见,但其实比较简单,下面通过代码了解它们的用法:


#include <stdio.h>

#include <errno.h>

#include <stdlib.h>

int main()
{

	char arr[20] = { 0 };

	FILE* pf = fopen("./data.txt", "w+");

	if (!pf)
	{
		perror("fopen");

		return EXIT_FAILURE;//1,需要<stdlib.h>
	}

	fputc('H', pf);

	fputs("ello,world!", pf);

	fseek(pf, 0, SEEK_END);

	int sz = (int)ftell(pf);//long int类型

	printf("文件内容大小是%d\n", sz);

	rewind(pf);

	arr[0] = fgetc(pf);//返回的是拷贝的字符的ASCII码值,返回int

	fgets(arr + 1, sz, pf);//get的个数是sz-1,最后有\0

	printf(arr);

	fclose(pf);

	pf = NULL;

	return 0;

}

(1)还有fprintf 和 fscanf也比较常见,但上面一条已经讲解,所以这里不再举例,只需要把首个参数从stdin或stdout换成文件操作流即可

(2)rewind(pf)是还原打开文件后光标的起始位置。当然, 也可以用 fseek(pf, 0, SEEK_SET)代替。而ftell是用来告诉此刻光标的偏移量的,这三个函数通常相互配合使用。

(3)fputc标准格式:int fputc ( int character, FILE * stream );

fputs标准格式:int fputs ( const char * str, FILE * stream );

fgetc标准格式:int fgetc ( FILE * stream );

fgets标准格式:char * fgets ( char * str, int num, FILE * stream );

还有两个二进制文件操作相关的函数:

fread标准格式:size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

fwrite标准格式:size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

这里要从右向左读:在stream这个流里,对count个size大小的数据进行读(写)操作。

这些函数都很容易理解,主要是注意参数的位置

(4)创建文件时前缀./表示在当前目录,./../表示在上级目录(../表示上级目录),可以嵌套使用,如./../.././../(但逻辑得自己捋清楚)

注意的是在绝对路径下表示文件地址的是\而不是这里的相对路径的/,两者有细微区别,注意细节

10.文件读取结束后的判断

一般情况下,我们使用feof和ferror来判断读取文件结束后是什么原因


#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

int main()
{

	int i = 0;

	FILE* pf = fopen("./data.txt", "r");

	if (!pf)
	{
		perror("fopen");

		return EXIT_FAILURE;

	}

	fprintf(pf, "Hola!");

	while (fgetc(pf) != EOF);
	
	if (feof(pf))
	{
		printf("成功读取完数据并退出\n");
	}
	else if (ferror(pf))
	{
		printf("读取时遇到了错误导致退出\n");
	}

	fclose(pf);

	pf = NULL;

	return 0;
}

在调用了一个函数后,文件信息区的信息会被更改,所以使用这两个函数直接传一个参数即可

C++实现memcpy函数 面试常见,C++实现memcpy函数 阅读详情

相关推荐

【C语言】memcpy函数的实现

1函数原型 void *memcpy(void *dest, const void *src, size_t n); 2功能 从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中 3所需头文件 C语言中使用#include ; C++中使用#include 和#include 都可以。 4返回值 函数返回指向dest的指针。 5说明 1.s

liuxiaoqian_的专栏 2832

【c++中内存拷贝函数(C++ memcpy)详解】

内存拷贝

qq_42222110的博客 9144

C++内存管理之堆栈区别、拷贝memcpy、分配malloc 与释放free

C++内存管理之拷贝memcpy、分配malloc 与释放free

yohnyang的博客 5761

[C++]memcpy函数的使用以及模拟实现

memcpy函数如何使用,以及如何实现我们自己的my_memcpy在这里给大家详细介绍。memcpy是c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。这些memcpy函数的全部内容了,主要就是讲解它的使用,以及我们自己如何去实现它。

FL1768317420的博客 3915

Python量化交易实战:pytdx库高效获取通达信分笔成交数据

本文详细介绍了如何使用Python的pytdx库高效获取通达信分笔成交数据,为量化交易提供关键市场微观结构分析。通过环境搭建、服务器连接、数据获取与清洗的完整流程,帮助开发者快速掌握这一免费高质量数据源,并实现分笔数据的实战分析与应用。

weixin_29061509的博客 1345

手机Camera硬件电路设计:从电源管理到信号完整性的实战解析

本文深入解析了手机Camera硬件电路设计的核心挑战与实战经验,重点聚焦于电源管理与信号完整性两大基石。文章详细阐述了AVDD、DVDD、IOVDD和AFVDD四路电源的差异化设计要点与噪声控制策略,并剖析了MIPI等高速信号通道的完整性设计原则,为硬件工程师提供了从理论到PCB布局布线的完整实战指南。

weixin_28308325的博客 249

c/c++内存函数(memcpy,memmove,memset,memcmp)的详解和自已实现

1)mempy指的是C和C++使用的内存拷贝函数, 函数原型为void* memcpy(void* destin, void* source, unsigned n); 函数的功能是从源内存地址的起始位置开始拷贝若干个字节到目标内存地址中, 即从源source中拷贝n个字节到目标destin中。函数原型 void *memcpy(void *destin, void *source, unsigned n); 参数 destin-- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。 sou

weixin_64812470的博客 5379

关于旋转矩阵的左乘与右乘问题

最近在阅读框架源码时被旋转矩阵左乘右乘绕的云里雾里,故写下一篇记录一下,以防自己不长记性。

菜鸡正在学习 1万+

C/C++相关概念和易错知识点(12)(字符数组的修改、sscanf、sprintf)

对于这个变量有一个特殊操作就是&arr,这个操作是取出整个数组的地址,整个数组的地址是首元素的地址,所以&arr和arr得到的值是相同的。arr这个指针还有个常属性,即arr存储的值不能被修改,类似于const int* p,这就导致arr的指向的空间区域在一开始就确定了,不能被修改了。在上面这张图中,我们可以看到如果我们想要将"Hello"存到数组,直接赋值操作是不行的,因为就像上面所说的,这个临时变量同样具有常属性,这个临时变量我们是看不到的,如果有变量接收就把这个临时变量的值赋给这个变量。

SGlow0708的博客 3188

CODESYS V3.5 SP17编程环境全攻略:从安装到多语言编程实战

本文全面解析CODESYS V3.5 SP17编程环境,从安装配置到多语言编程实战技巧。详细介绍了运行时环境设置、六种IEC 61131-3语言的特性对比与混合编程策略,以及高级功能开发如自定义算法模块和实时通信配置。适合工业自动化工程师快速掌握这一强大工具。

weixin_30632089的博客 489

保姆级避坑指南:在openEuler 22.03 LTS上用kubeadm 1.32.2部署K8s集群(含阿里云镜像加速)

本文提供在openEuler 22.03 LTS上使用kubeadm 1.32.2部署Kubernetes集群的详细指南,涵盖系统准备、容器运行时适配、kubeadm配置及集群初始化等关键步骤。特别针对openEuler系统的特殊性,解决软件源配置、cri-dockerd编译安装、阿里云镜像加速等常见问题,帮助用户高效完成K8s集群部署。

weixin_28312391的博客 273

使用memmove/memcpy库函数拷贝内存时容易产生的异常

使用memmove/memcpy库函数拷贝内存时容易引发的异常 首先,我们来看一下C库函数memmove的原型,如下: void memmove( void dest, const void* src, size_t n); 头文件:<string.h> 功能:由src所指内存区域复制n个字节到dest所指内存区域。 返回值:函数返回指向dest的指针。 其次,C库函数memc...

weixin_42463517的博客 7199

用PyTorch手把手搭建液态神经网络(LNN):从微分方程到无人机避障实战

本文详细介绍了如何使用PyTorch搭建液态神经网络(LNN),从微分方程基础到无人机避障实战应用。LNN通过动态时序建模和微分方程实现高效计算,特别适合多传感器数据融合场景。文章包含完整的代码实现、训练技巧及性能优化方案,帮助开发者快速掌握这一前沿技术。

uber9的博客 438

深入解析C/C++内存函数:从memcpy到memmove的实战避坑指南

内存操作是C/C++编程的核心基础,涉及对原始内存字节的直接读写,其核心原理在于绕过类型系统,以字节为单位进行高效处理。理解内存对齐、字节序等底层概念,对于编写高性能和健壮的系统软件至关重要。这些技术的价值在于提供了接近硬件极限的数据操作能力,广泛应用于网络编程、音视频处理、嵌入式系统及自定义数据结构实现等场景。本文将聚焦于memcpy、memmove、memset和memcmp这四个关键函数,通过剖析内存重叠、结构体填充字节等典型陷阱,并结合memcpy性能优化和memmove安全拷贝等实战案例,帮助开发

weixin_34379433的博客 369

OFDM调制matlab仿真详细代码

MATLAB仿真代码 % ================================================== % 作者: 肆拾伍 % 时间:11/30 2019 % 版本:V3 % =================OFDM仿真参数说明:================ % % 子载波数 carrier_count ---200 % 总符号数 symbol_count ...

肆拾伍的博客 3万+

2xmax96717+max96724+agx orin驱动代码

说明:这里主要解决max96717的设备地址和sensor地址映射,vc0->vc1多颗max96717+max96724使用配置思路如下: 1、改变max96717的pipez stream id,然后max96724的pipe绑定使用相应的stream id 2、max96717默认是vc0,把vc0改写成vc1\vc2\vc3,然后max96724再重新映射vc输出

mantouyouyou的博客 112

C/C++中的memcpy

这个函数的用法还是比较简单的,只是经常忘记,所以就记下来吧。 1. 所需头文件     2. 函数原型 void * memcpy ( void * destination, const void * source, size_t num ); (1) 复制指向source位置的num个字节的值直接到指向destination的内存区域中。 (2) source和de

songuo' s home 1万+

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

【C语言】精妙运用内存函数:深入底层逻辑的探索

上篇文章介绍了字符串相关函数,但是缺点在于只针对于字符类型。 本篇文章涉及的函数不单单只能用于字符类型的数据,通过内存进行修改适用于任意类型数据,逐字节修改。 内存函数大部分在string.h头文件中进行声明。

专注于 C/C++ 后端开发,涵盖基础语法、Linux系统与网络、MySQL数据库、常见算法及项目经验。 1819

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

【C语言】常见的内存函数使用(memcpy、memmove、memcmp以及memset的详细讲解)

我们在拷贝内容的时候同时也会改变arr1中的内容,所以就等于一边改变arr1数组中的内容一边将其拷贝到arr1数组中,并且只拷贝20个字节的内容,所以改变后的arr1的内容是1,2,1,2,3,4,5,6,7,8,我们将前20个字节的内容拷贝到了arr+2后面的内容,所以就成为了如上图所示的数组内容。void*类型的指针dest指向arr2数组中的首元素的地址,第二个参数void*类型的指针src指向arr1数组中的首元素的地址,第三个参数是整型参数意为传递20个字节;那就是要从前向后拷贝;

wangduduniubi的博客 2130

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

C++有关内存的那些事

C++有关内存的知识都有些什么?作用是什么?快来和PingdiGuo_guo一起来探索吧!

PingdiGuo_guo的博客 3355

C/C++内存函数深度解析:memcpy、memmove、memset、memcmp的正确使用与性能陷阱

内存操作是计算机程序设计的基石,理解内存的读写、复制与比较原理是每位开发者的必修课。在C/C++等系统级编程语言中,内存函数直接操作底层字节,其性能与正确性直接影响程序的效率与稳定性。这些函数通过高效的字节级处理,为数据结构初始化、数据迁移和二进制比较提供了基础支持,在系统编程、嵌入式开发和高性能计算中不可或缺。然而,看似简单的函数背后隐藏着诸多陷阱,例如**内存重叠**导致的未定义行为,以及**结构体填充字节**引发的比较错误。本文以`memcpy`、`memmove`、`memset`和`memcmp`

weixin_30388677的博客 310

【C语言】内存管理&&内存管理函数&&文件管理&&文件管理函数

【C语言】内存管理&&内存管理函数&&文件管理&&文件管理函数

m0_74722801的博客 1520

C/C++内存函数功能介绍与模拟实现

本文主要介绍了头文件string.h中包含的memcpy、memmove、memcmp、memset等库函数,并对其进行应用及模拟实现。帮助大家更加深刻的了解这些库函数。

2201_75880188的博客 397

C语言高手必知的内存拷贝陷阱(memcpy与memmove深度对比)

掌握C语言内存拷贝核心技巧,避开常见陷阱。深入解析C语言memcpy与memmove区别,涵盖内存重叠处理、适用场景及性能对比,揭示何时使用memmove避免数据损坏。理解底层原理,提升代码安全性与稳定性,值得收藏。

ProceShoal的博客 1011

c语言memcpy函数源代码,memcpy函数-memcpy函数,C语言

本教程分享:《memcpy函数》,memcpy是memorycopy的缩写,意为内存复制,在写C语言程序的时候,我们常常会用到它。它的函原型如下:.void*memcpy;.如果dest存在数据,将会被覆盖。memcpy函数的返回值是dest的指针。memcpy函数定义在string.h头文件里。memcpy函数memcpy指的是C和C++使用的内存拷贝函数,函数原型为void *memcpy(v...

weixin_35878217的博客 5914

C/C++内存函数深度解析:memcpy、memmove、memset、memcmp原理与实战避坑

内存操作是C/C++编程的基石,理解其底层原理对编写高效、安全的代码至关重要。内存函数通过直接操作字节实现数据复制、初始化和比较,其性能优化依赖于内存对齐和CPU指令集。在工程实践中,这些函数是数据结构序列化、缓冲区管理和内存池实现的核心工具。然而,不当使用会导致缓冲区溢出、数据覆盖等严重问题。本文聚焦memcpy与memmove的重叠处理差异、memset的字节操作特性以及memcmp的逐字节比较机制,结合内存对齐优化和编译器行为,深入探讨如何避免常见陷阱,确保代码健壮性。

weixin_34341229的博客 331
上一篇: C/C++相关概念和易错知识点(6)(字符串函数)
下一篇: C/C++相关概念和易错知识点(8)(预处理、编译、链接)
-SGlow-
博客等级 码龄3年 1513粉丝 118原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值