C/C++ string.h库中的memcpy()和memmove()

news2024/9/21 14:51:30

    不能把一个数组赋给另一个数组,所以要通过循环把数组中的每个元素赋给另一个数组相应的元素。有一个例外的情况是:使用strcpy()和strncpy()函数来处理字符数组。

    memcpy()和memmove()函数提供类似的方法处理任意类型的数组,下面是这两个寒素的原型:
        void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
        void *memmove(void *s1, const void *s2, size_t n);

    这两个函数都从s2指向的位置拷贝n字节到s1指向的位置,而且都返回s1的值。所不同的是memcpy()的参数带关键字restrict,即memcpy()假设两个内存区域之间没有重叠。

    而memmove()不做这样的假设,所以拷贝过程类似于先把所有字节拷贝到一个临时缓冲区,然后再拷贝到最终目的地。

    如果使用memcpy()时,两区域出现重叠会怎样?其行为时未定义的。这意味着该函可能正常工作。也可能失败。编译器不会再本该不使用memcpy()时禁止你使用,作为程序员,再使用该函数时有责任确保两个区域不重叠。

    由于这两个函数设计用于处理任何数据类型,所有它们的参数都是两个指向void的针。

    C允许把任何类型的指针赋给void*类型的指针。如此宽容导致函数无法知道待拷贝据的类型。因此这两个函数使用第3个参数指明待拷贝的字节数。

    需要注意的时,对数组而言,字节数与元素的个数不同。如果要拷贝数组中10个double
类型的元素,要使用10*sizeof(double),而不是10.

示例源码:

// Len_memcpy.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#define SIZE 10
#include <string>
using namespace std;

void PrintD(string s, int* data, int len)
{	
	printf("%s\t", s.c_str());
	for (int i = 0; i < len; i++)
	{
		printf("%d\t", data[i]);
	}
	printf("\n");
}
void PrintD(string s, double* data, int len)
{
	printf("%s\t", s.c_str());
	for (int i = 0; i < len; i++)
	{
		printf("%.2lf\t", data[i]);
	}
	printf("\n");
}
int main()
{
	int nValues[SIZE] = { 1,2,3,4,5,6,7,8,9,10 };
	double dValues[SIZE] = { 1.1, 2.2, 3.3, 4.4, 5.5,6.6,7.7,8.8,9.9, 0.1 };
	
	int memcpyN[SIZE] = {0};          // 使用memcpy拷贝数据到这里
	double memcpyD[SIZE] = {0.0};
	
	int memmoveN[SIZE] = { 0 };		 // 使用memmove拷贝数据到这里
	double memmoveD[SIZE] = { 0.0 };

	printf(" copy before: \n");
	PrintD("Values  ", nValues, SIZE);
	PrintD("dValues ", dValues, SIZE);
	PrintD("targetN ", memcpyN, SIZE);
	PrintD("targetD ", memcpyD, SIZE);

	printf("\n after memcpy copy: \n");
	memcpy(memcpyN, nValues, sizeof(int)*SIZE);
	memcpy(memcpyD, dValues, sizeof(int)*SIZE); // double比size占位宽,这里会丢失数据
	PrintD("Values  ", nValues, SIZE);
	PrintD("dValues ", dValues, SIZE);
	PrintD("memcpyN ", memcpyN, SIZE);
	PrintD("memcpyD ", memcpyD, SIZE);

	printf("\n after memmove copy: \n");
	memcpy(memmoveN, nValues, sizeof(int)*SIZE);
	memcpy(memmoveD, dValues, sizeof(double)*SIZE); // 这里不会再丢失数据
	PrintD("Values  ", nValues, SIZE);
	PrintD("dValues ", dValues, SIZE);
	PrintD("memmoveN", memmoveN, SIZE);
	PrintD("memmoveD", memmoveD, SIZE);
}

执行结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1325618.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

idea插件在线和离线安装

在线安装 idea在线安装插件比较简单明了&#xff0c;打开setting&#xff08;或者快捷键ctrlalts&#xff09;&#xff0c;找到plugins查找要安装的插件&#xff0c;点击安装&#xff0c;重启idea 离线安装 在官网下载插件安装包 jetbrains官网插件地址 打开idea&#xff0c…

使用HTTP协议有哪些风险?HTTP与HTTPS的区别是什么

作为两种常见的网络协议&#xff0c;HTTP和HTTPS都是用于在浏览器和服务器之间传输数据的。然而在保障数据安全性方面&#xff0c;HTTPS远远优于HTTP。在网络安全愈发重要的当下&#xff0c;HTTP协议的不安全性使得其逐渐被淘汰弃用。那么使用HTTP协议有哪些风险呢&#xff1f;…

在mt5上哪里可以添加指数品种?

在MT5交易平台上&#xff0c;您可以通过以下步骤添加指数品种&#xff08;如股票指数、商品指数等&#xff09;到您的市场观察窗口中&#xff1a; Exness手机登录平台学习指南 步骤一&#xff1a;打开市场观察窗口&#xff1a; 打开MT5交易平台。 在左侧的“市场观察”窗口中&…

c语言:指针作为参数传递

探究实参与形参它们相互独立 由于主调函数的变量a&#xff0c;b与被调函数的形参x&#xff0c;y它们相互独立。函数 swap 可以修改变量x&#xff0c;y&#xff0c;但是却无法影响到主调函数中的a&#xff0c;b。 现在利用取地址运算符&#xff0c;分别打印它们的首地址&#x…

【PHP入门】2.2 流程控制

-流程控制- 流程控制&#xff1a;代码执行的方向 2.2.1控制分类 顺序结构&#xff1a;代码从上往下&#xff0c;顺序执行。&#xff08;代码执行的最基本结构&#xff09; 分支结构&#xff1a;给定一个条件&#xff0c;同时有多种可执行代码&#xff08;块&#xff09;&am…

抖音达人筛选需要注意什么,投放总结

商家想要在抖音开拓市场&#xff0c;带动产品销路&#xff0c;寻找达人投放是必行之道。那么抖音达人筛选需要注意什么&#xff0c;我们为大家总结了如下流程。 一、以基础数据找达人 以基础数据进行抖音达人筛选&#xff0c;可以称得上是很直接的方法了。这里的接触数据包括粉…

安防视频融合云平台/智慧监控平台EasyCVR如何添加验证码调用接口?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

机器学习 | 聚类Clustering 算法

物以类聚人以群分。 什么是聚类呢&#xff1f; 1、核心思想和原理 聚类的目的 同簇高相似度 不同簇高相异度 同类尽量相聚 不同类尽量分离 聚类和分类的区别 分类 classification 监督学习 训练获得分类器 预测未知数据 聚类 clustering 无监督学习&#xff0c;不关心类别标签 …

红队打靶练习:WINTERMUTE: 1

前言 网络扫描&#xff08;Nmap、netdiscover&#xff09; HTTP 服务枚举 使用电子邮件日志文件在浏览器中进行目录遍历 利用 SMTP RCPT 选项中的操作系统命令注入 生成 PHP 后门 (Msfvenom) 执行RCPT选项中嵌入的后门 反向连接&#xff08;Metasploit&#xff09; 导入 pytho…

C++_动态二维数组的两种方法

介绍 本文主要介绍使用 动态二维数组的两种方法 (PS:仅作创建 动态二维数组参考,详细使用方法根据需求自行改变) 第一种&#xff1a;连续存储结构的 二维动态数组(需固定 列 大小&#xff0c;可通过下标访问) 缺点: 1.需要在设计二维数组前写死 列 的大小 2.空间利用率不高 优点…

armv8-a发展历程

ARMv8-A 架构是针对应用配置文件的最新一代 ARM 架构。ARMv8 这个名称用于描述整体架构&#xff0c;现在包括 32 位执行和 64 位执行。它引入了使用 64 位宽寄存器执行执行的能力&#xff0c;同时保留了与现有 ARMv7 软件的向后兼容性。 ARMv8-A 架构引入了许多变化&#xff0c…

深入理解网络 I/O:FileOutputStream、BufferFileOutputStream、ByteBuffer

&#x1f52d; 嗨&#xff0c;您好 &#x1f44b; 我是 vnjohn&#xff0c;在互联网企业担任 Java 开发&#xff0c;CSDN 优质创作者 &#x1f4d6; 推荐专栏&#xff1a;Spring、MySQL、Nacos、Java&#xff0c;后续其他专栏会持续优化更新迭代 &#x1f332;文章所在专栏&…

BEVFusion-mit复现与实践(nuscenes-mini数据集)

目录 一、CUDA版本11.1二、创建虚拟环境并激活三、安装pytorch四、安装openmpi五、安装功能包六、源码下载七、参数修改与编译八、配置nuscenes-mini九、复现十、实践 一、CUDA版本11.1 二、创建虚拟环境并激活 conda create -n bevfusion python3.8 conda activate bevfusio…

C# NPOI导出dataset----Excel绘制Chart图表

仅限XLSX 2007以后版本&#xff08;2007之前版本不支持&#xff09; 1、判断文件夹是否存在&#xff0c;不存在则创建 //Application.StartupPath当前项目根目录 if (!Directory.Exists(Application.StartupPath "\Excel")) { …

高通平台开发系列讲解(USB篇)adb应用adbd分析

沉淀、分享、成长,让自己和他人都能有所收获!😄 在apps_proc/system/core/adb/adb_main.cpp文件中main()函数会调用adb_main()函数,然后调用uab_init函数 在uab_init()函数中,会创建一个线程,在线程中会调用init_functionfs()函数,利用ep0控制节点,创建ep1、ep2输…

Git报错x509: certificate signed by unknown authority

下载报错&#xff1a; Error downloading object: model-00001-of-00008.safetensors (ed3ac49): Smudge error: Error downloading model-00001-of-00008.safetensors (ed3ac4983f682a999b0e4b6f072aad294c4fd9a7e968e90835ba5c4b466d3c7c): LFS: Get https://cdn-lfs.huggin…

可定制化的企业电子招标采购系统源码

随着企业的快速发展&#xff0c;招采管理逐渐成为企业运营中的重要环节。为了满足公司对内部招采管理提升的要求&#xff0c;建立一个公平、公开、公正的采购环境至关重要。在这个背景下&#xff0c;我们开发了一款电子招标采购软件&#xff0c;以最大限度地控制采购成本&#…

maven限制内存使用峰值/最大内存

前言 通过设置虚拟机的内存大小&#xff0c;达到限制maven内存使用峰值的效果 方法1&#xff1a;修改mvn脚本 找到mvn脚本在MAVEN_OPTS参数值添加-Xms、-Xmx参数&#xff1a;MAVEN_OPTS"$MAVEN_OPTS -Xms512m -Xmx512m"效果图 windows系统下修改MAVEN_OPTS参数 …

31 在Vue3中如何使用slot插槽

概述 插槽在真实的开发中使用非常的多&#xff0c;比如我们去用一些第三方组件库的时候&#xff0c;通常都需要通过自定义插槽来实现内容的自定义。 在Vue3中使用插槽非常的简单。 插槽相当于在组件中给你预留一块位置&#xff0c;你可以将自己的vue3相关的代码插入到这个位…

netty源码:(29)ChannelInboundHandlerAdapter

它实现的方法都有一个ChannelHandlerContext参数&#xff0c;它的方法都是直接调用ChannelHandlerContext参数对应的方法&#xff0c;该方法会调用下一个handler对应的方法。 可以继承这个类&#xff0c;重写感兴趣的方法,比如channelRead. 这个类有个子类&#xff1a;SimpleC…