C-基础:memcpy、memset、memmove、memcmp、memchr
一,原型
void * memcpy ( void * destination, const void * source, size_t num );
功能:将以source作为起始地址的数据复制num个字节到以destination为起始地址的数据中,不支持destination和source重叠的情况。函数返回destination指针。
- void* memcpy (void* destination,constvoid* source,size_t num )
- {
- char* pdes =(char*)destination;
- char* psrc =(char*)source;
- assert(destination !=NULL && source !=NULL && num>);
- while(num--)
- *pdes++=*psrc++;
- return destination;
- }
- void* memmove (void* destination,constvoid* source,size_t num )
- {
- char* pdes =(char*)destination;
- char* psrc =(char*)source;
- assert(destination !=NULL && source !=NULL && num>);
- //判断destination和source是否存在重叠
- if(pdes+num <psrc || psrc+num < pdes)//不存在重叠,正常从前向后复制
- while(num--)
- *pdes++=*psrc++;
- else//存在重叠,防止信息丢失,从后向前复制
- {
- pdes = pdes+num-;
- psrc = psrc+num-;
- while(num--)
- *pdes--=*psrc--;
- }
- return destination;
- }
- void* memset (void* ptr,int value,size_t num )
- {
- char* ptmp =(char*)ptr;
- assert(ptr !=NULL && num >);
- while(num--)
- *ptmp++= value;
- return ptr;
- }
- int memcmp (const void* ptr1,const void* ptr2,size_t num )
- {
- int ret =;
- const char* ptmp1 =(char*)ptr1;
- const char* ptmp2 =(char*)ptr2;
- assert(ptr1 != NULL && ptr2 != NULL && num>);
- while(num--)
- {
- if(*ptmp1 >*ptmp2)
- {
- ret =;
- break;
- }
- if(*ptmp1 <*ptmp2)
- {
- ret =-;
- break;
- }
- ptmp1++;
- ptmp2++;
- }
- return ret;
- }
- void* memchr (void* ptr,int value,size_t num )
- {
- char* pret = NULL;
- char* ptmp =(char*)ptr;
- assert(ptr !=NULL && num>);
- while(num)
- {
- if(*ptmp == value)
- {
- pret = ptmp;
- break;
- }
- ptmp++;
- num--;
- }
- return pret;
- }
二,详解
memcpy函数详解
void *memcpy( void *dest, const void *src, size_t count );
作用:
在dest处拷贝src处的字节,并以count来计算需要拷贝的字节数量,进行内存的拷贝。
参数:
dest:新的存贮区的开始部位
src:需要拷贝的开始部位
count:需要拷贝的字节数
备注:
dest,src,它们都是从各自的地址处进行写入,如果是p而不是&p,那么将会取得p的值(地址),在该值的地址处进行读出或写入。
例:
- int* intPoint = new int();
- int* intPoint1;
- memcpy( &intPoint1, &intPoint, );//在intPoint1的地址处写入intPoint地址处的值,也就是intPoint指针值。
- cout << *intPoint1 << endl; //使intPoint1指向了intPoint.
或
- int* intPoint = new int();
- int intPoint1;
- memcpy( &intPoint1, intPoint, );
- cout << intPoint1 << endl;
2)
memcpy函数的实现与应用
memcpy函数较memmove相比,存在的不足是没有考虑到目的地址与源地址相重合,本文对memcpy作了修改,弥补其不足。
memcpy函数的特点是:
1. 使用memcpy函数前,实参dest必须初始化,否则可能会出错,原因见2。
2. 函数原理是将void *src 强制转换为char *s,然后只负责拷贝n个字节到dest里,不负责在最后加上'\0'。
下面的代码其实是实现了memmove的功能,然后根据memcpy的参数为void*,给其分别尝试传入int*和char*,以此来掌握int*是如何转化为char*,及强制转化后是什么结果,涉及到大端和小端等等。
- #include <stdio.h>
- #include <string.h>
- void * mymemcpy(void *dest,void *src, int n)
- {
- char *d;
- char *s;
- int i=;
- s=(char *)src;
- d=(char *)dest;
- if(dest==NULL || src==NULL || n<)
- return ;
- if(d>=s && d<=s+n-)
- {
- i=n-;
- printf("%d\n",i);
- while(i>=)
- {
- d[i]=s[i];
- i--;
- }
- }
- else
- {
- while(i<n)
- {
- //printf("%x ",s[i]);
- d[i]=s[i];
- //printf("i=%d %x\n",i,d[i]);
- i++;
- }
- d[i]='\0';
- }
- dest=(void *)d;
- return dest;
- }
- int main(char **argv,int argc)
- {
- //情况1
- char src[]="helloworldhui";
- //如果是特殊情况mymemcpy(src+2,src,7);,则不可写成char *src="helloworld"; 因为文字常量区内容不可被改变
- //char dest[100]=""; //必须初始化
- char *dest;
- dest=(char *)mymemcpy(src+,src,);
- printf("%s\n",dest);//*/
- //情况2
- /* int src=123456789 ; //对应十六进制:75BCD15
- int dest=0;
- //dest必须初始化,不然,如果只拷贝3个字节时,dest的第四个字节未被赋值,这样输出会出错。
- memcpy(&dest,&src,3); //只能传递参数4,不然出错
- //mymemcpy(&dest,&src,3) //则拷贝前3个字节
- printf("dest=%d %x\n",dest,dest);//*/
- //情况3
- /* int src[100]={1234,12345,123456,11234567,14,15};
- int dest[100]={0};
- int i;
- memcpy(dest,src,13); //只拷贝13个字节
- //不能保证拷贝一个完整的整数,一个元素,即如果你输入13,3*4=12,只能保证前3个整数完整拷贝,
- //到了第4个整数,只拷贝它的第一个字节,如例为7
- //mymemcpy(dest,src,13);
- for( i=0;i< 5;i++)
- printf("*%d*\n",dest[i]);//*/
- return ;
- }
- // 为情况3的输出结果:
- #include <stdio.h>
- int main(void)
- {
- // int src[10]={50,61,72,83,94};
- _int64 src=; //0x75BCD15,它在内存中的存放从低地址,低字节开始:15,cd,5b,7
- char *p;
- int count;
- p=(char *)(&src);
- for(count=; count<sizeof(int);p++,count++)
- printf("第%d字节处十六进制值是: %02x\n",count,*p);
- return ;
- }
C-基础:memcpy、memset、memmove、memcmp、memchr的更多相关文章
- 41.内存函数实现(memcpy,memset,memmove,memicmp,memchr.memccpy)
memcpy #include <stdio.h> #include <stdlib.h> #include <memory.h> void * mymemcpy( ...
- memcpy、memmove、memset、memchr、memcmp、strstr详解
第一部分 综述 memcpy.memmove.memset.memchr.memcmp都是C语言中的库函数,在头文件string.h中.memcpy和memmove的作用是拷贝一定长度的内存的内容,m ...
- memcpy、memmove、memset及strcpy函数实现和理解
memcpy.memmove.memset及strcpy函数实现和理解 关于memcpy memcpy是C和C++ 中的内存拷贝函数,在C中所需的头文件是#include<string.h> ...
- strcpy()、memcpy()、memmove()、memset()的内部实现
一直想知道 strcpy().memcpy().memmove().memset()的内部实现 strcpy(), 字符串拷贝. char *strcpy(char *strDest, const c ...
- 不使用库函数、自己编写的(strlen、strcpy、strcmp、strcat、memcmp、memcpy、memmove)
不使用库函数.自己编写的(strlen.strcpy.strcmp.strcat.memcmp.memcpy.memmove) //求字符串长度的函数 int my_strlen(const char ...
- 关于memcpy和memmove的一点说明
今天看到书上降到memcpy和memmove的区别才突然发现原来两者之间有如此区别,以前只知道这两个函数是 实现同样的功能,没有接触到其不同. memcpy和memmove在MSDN的定义如下: 从两 ...
- memcpy vs memmove
[本文连接] http://www.cnblogs.com/hellogiser/p/memcpy_vs_memmove.html [分析] memcpy与memmove的目的都是将N个字节的源内存地 ...
- memcpy与memmove的区别
在面试中经常会被问道memcpy与memove有什么区别? 整理如下: 其实主要在考C的关键字:restrict C库中有两个函数可以从一个位置把字节复制到另一个位置.在C99标准下,它们的原型如下: ...
- C语言实现memcpy和memmove
0.两者比较: memmove用于从src拷贝count个字符到dest,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中.但复制后src内容会被 ...
- 第 16 章 C 预处理器和 C 库(string.h 库中的 memcpy() 和 memmove())
/*----------------------------------------- mems.c -- 使用 memcpy() 和 memmove() ---------------------- ...
随机推荐
- pymssql读取varchar字段中文显示乱码的问题分析
问题 用python的pymssql模块读取旧业务系统后台SQL Server 2000数据库展示数据为乱码 开发环境 操作系统:windows 8 数据库 MS SQL Server 2000,默认 ...
- 分区时"磁盘上没有足够的空间完成此操作"的解决方法
在新的预装windows 7的品牌机上,工作人员一般将磁盘分为C.D两个分区.但往往造成C盘有很大一部分的空间没办法分出来,而分出来的部分空间又不能和后面的磁盘合并,甚至出现无法新建简单卷的操作,即点 ...
- hdu5829 Rikka with Subset
首先考虑本题的$O(n^2)$做法. $Part1$ 对原序列从大到小排序后,考虑每个数字对最终答案的贡献,有第x个数字对答案的贡献十分难以计算,所以考虑计算数字x是集合第K大的方案数,作为数字x对$ ...
- A. Meeting of Old Friends
time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...
- Programming With Objective-C---- Encapsulating Data ---- Objective-C 学习(三) 封装数据
Programming with Objective-C Encapsulating Data In addition to the messaging behavior covered in t ...
- iOS开发检测是否开启定位、是否允许消息推送等权限
1.iOS开发检测是否开启定位: 需要导入: #import <CoreLocation/CoreLocation.h> 代码如下: + (void)openLocationService ...
- P1223 [小数据版]边权差值最小的生成树
这道题和最小生成树kruskal的代码几乎相同,只不过不一定是最小生成树,所以不一定从最短的边开始做生成树:所以将每一条边分别作为起点,然后枚举就行了...... #include <bits/ ...
- hdu1829&&poj2492 A Bug's Life 基础种类并查集
把性别相同的虫子放在同一个集合,然后每读入一对虫子号,判断它们在不在同一集合,在则同性别,不在则继续 #include <cstdio> #include <cstring> ...
- 无法获得VMCI 驱动程序的版本: 句柄无效的解决方法
关闭虚拟机,找到安装路径,用记事本打开.vmx结尾的文件 将vmci0.present = "TRUE"改为vmci0.present = "FALSE"保存
- 1-17finally关键字
finally的特点 被finally控制的语句体一定会执行,除非在执行finally语句体之前JVM退出(比如System.exit(0)),一般用于关闭资源 finally如何使用? finall ...