c语⾔中memcpy是字节⼤⼩,使⽤memcpy函数时要注意拷贝
数据的长度
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)的写法。
sprintf、strcpy 及 memcpy 函数区别
这些函数的区别在于 实现功能 以及 操作对象 不同.strcpy 函数操作的对象是 字符串 ,完成 从 源字符串 到 ⽬的字符串 的 拷贝 功能. sprintf 函数操作的对象 不限于字符串 :虽然 ...
memmove和memcpy函数的区别及实现
⼀.memmove()和memcpy()函数和strcpy()函数的区别: (1)使⽤的类型不同,strcpy()函数只对字符串进⾏操作:memmove()和memcpy()函数对所有类型都适⽤,为内 ...
⼀个按⽐特位拷贝数据的函数copybits
⼀个按⽐特位拷贝数据的函数 没有进⾏特别的优化.其实还可以在拷贝源开始位置和⽬标开始位置是2的整数倍位置的时候进⾏优化. 说明 这个函数⽤于从src数组⾸地址跳过sbb个字节,⼜跳过ssb个⽐特位,拷 ...
ajax请求为异步操作时,返回的数据不会被并列函数执⾏
ajax请求为异步操作时,返回的数据不会被并列函数执⾏
C语⾔之memcpy函数
昨天⾃⼰动⼿实现memcpy这个函数,⽤⼀个例程试了⼀下,结果正确,满⼼欢⼼,可是有些地⽅想不明⽩,于是百度了⼀下,结果⾃⼰写的函数简直⽆法直视. 觉得还是写个总结,以⽰教训. 先贴上我⾃⼰的函数: ...
jquery是什么有什么作用memcpy函数的使⽤⽅法
c和c++使⽤的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到⽬标dest所指的内存地址的起始位置中. 1.函数原型 void *memcpy(void * ...
memset和memcpy函数、atoi函数
memset void *memset(void *s,int c,size_t n) 总的作⽤:将已开辟内存空间 s 的⾸ n 个字节的值设为值 c.如下: // 1.将已开辟内存空间s 的⾸n个字节 ...
实现memcpy()函数及过程总结
1.为什么会写memcpy 在之前的应聘笔试上遇到⼀道笔试题,题⽬要求实现⼀个my_memcpy函数.函数原型:void * my_memcpy(void
*dst, const void *src, ...
C/C++ memcpy函数的⽤法
功能 memcpy指的是c和c++使⽤的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到⽬标dest 所指的内存地址的起始位置中 头⽂件 所在头⽂件
随机推荐
JS 控制CSS样式表
JS控制CSS所使⽤的⽅法:  你想要改变把他的display属性由none改为inline.  ...
spring之BeanFactoryAware接⼝
springBeanFactoryAware (转)要直接在⾃⼰的代码中读取spring的bean,我们除了根据常⽤的set外,也可以通过spring的BeanFactoryAware接⼝实现,只要实 ...
java Literals
Primitive Data Types The Java programming language is statically-typed, which means that all variabl ...
jQuery - Chaining
jQuery - Chaining @(编程) 通过 jQuery,您可以把动作/⽅法链接起来. Chaining 允许我们在⼀条语句中允许多个 jQuery ⽅法(在相同的元素上). jQuery ...
基于jQuery的宽屏可左右切换的焦点图插件
之前分享了很多实⽤的jQuery焦点图插件,⼤家可以看看.今天要继续为⼤家分享⼀款很不错的jQuery焦点图插件,它是宽屏展⽰的,⽽且有两个⼤⽓的按钮⽤来左右切换图⽚.效果图如下: 在线预览  源码 ...
Sql Server——查询(⼆)
上次写了查询⾥的⼀些简单的查询⽅法,如果说上次的是初级查询,那这次的就是⾼级查询了. 今天主要是聚合函数.分组查询.连接查询.联合查询.在我看来前三个挺简单的,稍微难理解点的也就最后⼀个,为什么呢?因 ...
Python 学习 第⼗六篇:networkx
networkx是Python的⼀个包,⽤于构建和操作复杂的图结构,提供分析图的算法.图是由顶点.边和可选的属性构成的数据结构,顶点表⽰数据,边是由两个顶点唯⼀确定的,表⽰两个顶点之间的关系.顶点和边 ...
centos6.7不联⽹的情况下安装配置本地yum源
1  cd /
2 mkdir -p /app/ios
3  cd /opt    mkdir ios
4  把下载好的centos-6.7-x86_64-bin-dvd1.iso  上传到 /o ...
JVM—内存溢出、OutOfMemoryError、StackOverflowError
【C#】简单计算器源代码
form1.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.D ...

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。