memcpy函数简介

memcpy函数是C/C++语言中的一个用于内存复制的函数,声明在 string.h 中(C++是 cstring)。其原型是:

void *memcpy(void *destin, void *source, unsigned n);

作用是:以source指向的地址为起点,将连续的n个字节数据,复制到以destin指向的地址为起点的内存中。

函数有三个参数,第一个是目标地址,第二个是源地址,第三个是数据长度。

使用memcpy函数时,需要注意:

  • 数据长度(第三个参数)的单位是字节(1byte = 8bit)。
  • 注意该函数有一个返回值,类型是void*,是一个指向destin的指针。

memcpy函数复制的数据长度

使用memcpy函数时,特别要注意数据长度。

如果复制的数据类型是char,那么数据长度就等于元素的个数。而如果数据类型是其他(如int, double, 自定义结构体等),就要特别注意数据长度的值。

好的习惯是,无论拷贝何种数据类型,都用 n * sizeof(type_name)的写法。

先以最简单的情况说明:

    char a[10] = "abcdefgh";
unsigned n = 2;
void * p = memcpy(a+3, a, n);

以上代码将从a开始的两个字节的数据(即'a'和'b'),复制到从a+3开始的内存('d'所在的地址)。这样,'d'和'e'被替换。

执行结束之后,字符数组(字符串)a的内容变为"abcabfgh",返回值p即为a的地址(p == a)。

再以int类型为例说明:

    int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
unsigned n = 5;
void * p = memcpy(a+3, a, n);

int类型的长度是4个字节。以上代码将从a开始的5个字节的数据复制。5个字节的数据是什么呢?前四个字节组成了一个完整的int(即第一个元素0)。第五个字节,只能取到第二个元素的第1个字节。这里又会涉及到big-endian和little-endian的问题。假设是小端方式储存(更常见),那么读到的是元素1的低8位,写成十六进制即0x1

目标地址是a+3。由于指针加减常数,单位是与类型保持一致的,也就是在a的基础上,增加3倍int长度,对应的是元素3的地址。元素3被替换为0。元素4写成十六进制是0x0004,低8位被替换为0x1,变为0x0001

所以执行结束之后,数组a的内容变为 { 0, 1, 2, 0, 1, 5, 6, 7, 8, 9 },返回值p即为a的地址(p == a)。

根据上面的解释,如果把程序里的n改为6、7、8,那么结果都是一样的。因为数字1和4的二进制表示除了低8位不同,高位都是0。

倘若高位不相同,那么结果就没那么简单了。还是以int数组为例:

    int a[10] = { 0, -1, 2, 3, 4, 5, 6, 7, 8, 9 };
unsigned n = 5;
memcpy(a+3, a, n);

复制5个字节的数据,前4个字节组成了一个int,即第一个元素0。那么元素3被替换为0。第5个字节从-1中取。-1的十六进制表示为0xFFFF,第5个字节的数据是0xF。元素4变为0x000F,即15。数组a变为 { 0, -1, 2, 0, 15, 5, 6, 7, 8, 9 }。

如果 n = 6,那么4变为```0x00FF``,即255。数组a变为 { 0, -1, 2, 0, 255, 5, 6, 7, 8, 9 }。

可以看出,如果你想用memcpy复制元素,那么一定要写对数据长度。如果要完整地复制 n 个 int 类型元素,那么写法如下:

    int a[10] = { 0, -1, 2, 3, 4, 5, 6, 7, 8, 9 };
unsigned n = 5 * sizeof(int);
memcpy(a+3, a, n);

数组a变为 { 0, -1, 2, 0, -1, 2, 0, -1, 8, 9 }。

如果是其他类型,用法也是一样的。

好的习惯是,如果拷贝何种数据类型,都用 n * sizeof(type_name)的写法。

使用memcpy函数时要注意拷贝数据的长度的更多相关文章

  1. sprintf、strcpy 及 memcpy 函数区别

    这些函数的区别在于 实现功能 以及 操作对象 不同.strcpy 函数操作的对象是 字符串 ,完成 从 源字符串 到 目的字符串 的 拷贝 功能. sprintf 函数操作的对象 不限于字符串 :虽然 ...

  2. memmove和memcpy函数的区别及实现

    一.memmove()和memcpy()函数和strcpy()函数的区别: (1)使用的类型不同,strcpy()函数只对字符串进行操作:memmove()和memcpy()函数对所有类型都适用,为内 ...

  3. 一个按比特位拷贝数据的函数copybits

    一个按比特位拷贝数据的函数 没有进行特别的优化.其实还可以在拷贝源开始位置和目标开始位置是2的整数倍位置的时候进行优化. 说明 这个函数用于从src数组首地址跳过sbb个字节,又跳过ssb个比特位,拷 ...

  4. ajax请求为异步操作时,返回的数据不会被并列函数执行

    ajax请求为异步操作时,返回的数据不会被并列函数执行

  5. C语言之memcpy函数

    昨天自己动手实现memcpy这个函数,用一个例程试了一下,结果正确,满心欢心,可是有些地方想不明白,于是百度了一下,结果自己写的函数简直无法直视. 觉得还是写个总结,以示教训. 先贴上我自己的函数: ...

  6. memcpy函数的使用方法

    c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中. 1.函数原型 void *memcpy(void * ...

  7. memset和memcpy函数、atoi函数

    memset void *memset(void *s,int c,size_t n) 总的作用:将已开辟内存空间 s 的首 n 个字节的值设为值 c.如下: // 1.将已开辟内存空间s的首n个字节 ...

  8. 实现memcpy()函数及过程总结

    1.为什么会写memcpy 在之前的应聘笔试上遇到一道笔试题,题目要求实现一个my_memcpy函数.函数原型:void * my_memcpy(void *dst, const void *src, ...

  9. C/C++ memcpy函数的用法

    功能 memcpy指的是c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中 头文件 所在头文件 <s ...

随机推荐

  1. 【python】raise_for_status()抛出requests.HTTPError错误

    1.首先看下面代码的运行情况 import requests res = requests.get("https://www.csdn.net/eee", headers=head ...

  2. test20190925 老L

    100+0+0=100.概率题套路见的太少了,做题策略不是最优的. 排列 给出 n 个二元组,第 i 个二元组为(ai,bi). 将 n 个二元组按照一定顺序排成一列,可以得到一个排列.显然,这样的排 ...

  3. CentOS7.6安装docker最新版

    注意Centos7.4系统以下需要升级内核,否则会安装失败 yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config ...

  4. MySQL命令操作(Linux平台)

    Linux shell 批量创建数据库/表 Shell 脚本如下: # create database and table HOST='localhost' PORT='3306' USER='roo ...

  5. CentOS yum repo

    CentOS yum repo   阿里云的 一个是Centos-6的 一个是Centos-7  # CentOS 5 wget -O /etc/yum.repos.d/CentOS-Base.rep ...

  6. HTML5 文件读取

    一.定义 input的file类型会渲染为一个按钮和一段文字.点击按钮可打开文件选择窗口,文字表示对文件的描述(大部分情况下为文件名):file类型的input会有files属性,保存着文件的相关信息 ...

  7. Codevs 1305 Freda的道路(矩阵乘法 DP优化)

    1305 Freda的道路 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description Freda要到Rainbow的城堡去玩了.我们可以认 ...

  8. mysql 创建时间字段

    alter table table1 add order_date datetime null; mysql> select * from table1; +----------+------- ...

  9. fluent计算输出时均值

    / ****************************************************************************** * Created on : 2017 ...

  10. #C++初学记录(算法效率与度量)

    时间性能 算法复杂性函数: \[ f(n)=n^2 +1000n+\log_{10}n+1000 \] 当n的数据规模逐渐增大时,f(n)的增长趋势: 当n增大到一定值以后,计算公式中影响最大的就是n ...