我的memcmp:

 int memcmp(void *buf1, void *buf2, unsigned int count){
int reval;
while(count && !(reval = (*(unsigned char *)buf1) - (*(unsigned char *)buf2)))
{
buf1 = (unsigned char *)buf1 + ;
buf2 = (unsigned char *)buf2 + ;
--count;
}
return reval;
}

MS VC:

int __cdecl memcmp (
const void * buf1,
const void * buf2,
size_t count
)
{
if (!count)
return(); while ( --count && *(char *)buf1 == *(char *)buf2 ) {
buf1 = (char *)buf1 + ;
buf2 = (char *)buf2 + ;
} return( *((unsigned char *)buf1) - *((unsigned char *)buf2) );
}

应该使用const void *buf为宜,不改变该块内存的内容,最终使用unsigned char *进行运算,保证运算结果的符号正确。

我的memcpy:

 void *memcpy(void *dest, const void *src, unsigned int count){
void *reval = dest;
while(count--){
(*(unsigned char *)dest++) = (*(unsigned char *)src++);
}
return reval;
}

MSVC:

 void * __cdecl memcpy (
void * dst,
const void * src,
size_t count
)
{
void * ret = dst; #if defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC)
{
extern void RtlMoveMemory( void *, const void *, size_t count ); RtlMoveMemory( dst, src, count );
}
#else /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
/*
* copy from lower addresses to higher addresses
*/
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + ;
src = (char *)src + ;
}
#endif /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */ return(ret);
}

我的memmove:

 void *memmove(void *dest, const void *src, unsigned int count){
void *reval = dest;
int overlap = ((unsigned char *)src < (unsigned char *)dest && ((unsigned char *)src + count) > dest);
while(count--){
if(overlap)//src is in front of dest and overlap. copy direction is from endIndex to beginIndex
(*((unsigned char *)dest + count)) = (*((unsigned char *)src + count));
else
(*(unsigned char *)dest++) = (*(unsigned char *)src++);
}
return reval;
}

MSVC:

 void * __cdecl memmove (
void * dst,
const void * src,
size_t count
)
{
void * ret = dst; #if defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC)
{
extern void RtlMoveMemory( void *, const void *, size_t count ); RtlMoveMemory( dst, src, count );
}
#else /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
if (dst <= src || (char *)dst >= ((char *)src + count)) {
/*
* Non-Overlapping Buffers
* copy from lower addresses to higher addresses
*/
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + ;
src = (char *)src + ;
}
}
else {
/*
* Overlapping Buffers
* copy from higher addresses to lower addresses
*/
dst = (char *)dst + count - ;
src = (char *)src + count - ; while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst - ;
src = (char *)src - ;
}
}
#endif /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */ return(ret);
}

关于memcpy和memmove的区别,memcpy不考虑内存区域重叠的情况而memmove保证内存区域重叠也能正常复制成功。

有时候我们的memcpy也可能在内存重叠的情况下正常使用,这取决于它的实现,不具有普遍性,C语言标准中未对其有这种要求。

参考资料:

《关于memcpy和memmove两函数的区别》

http://blog.csdn.net/caowei840701/article/details/8491836

《memcpy() vs memmove()》

http://stackoverflow.com/questions/4415910/memcpy-vs-memmove

我的memset:

 void *memset(void *buffer, int c, int count){
void *reval = buffer;
while(count--){
(*(unsigned char *)buffer++) = (unsigned char)c;
}
return reval;
}

MSVC:

 void * __cdecl memset (
void *dst,
int val,
size_t count
)
{
void *start = dst; #if defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC)
{
extern void RtlFillMemory( void *, size_t count, char ); RtlFillMemory( dst, count, (char)val );
}
#else /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
while (count--) {
*(char *)dst = (char)val;
dst = (char *)dst + ;
}
#endif /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */ return(start);
}

走进C标准库(7)——"string.h"中函数的实现memcmp,memcpy,memmove,memset的更多相关文章

  1. 走进C标准库(8)——"string.h"中函数的实现相关字符串操作函数

    我的strcat: char *strcat(char *dest,char *src) { char * reval = dest; while(*dest) dest++; while(*src) ...

  2. 走进C标准库(6)——"string.h"中函数的实现memchr

    我写的memchr: void *memchr(const void *buf, char ch, unsigned count){ unsigned ; while(*(buf++) != ch & ...

  3. 走进C标准库(3)——"stdio.h"中的getc和ungetc

    接前文. 再来看看getc和ungetc的实现.在看这两个函数的实现之前,我们先来想一想这两个函数分别需要做的工作. int getc(FILE *stream) 说明:函数getc从stream指向 ...

  4. 走进C标准库(2)——"stdio.h"中的fopen函数

    其他的库文件看起来没有什么实现层面的知识可以探究的,所以,直接来看stdio.h. 1.茶余饭后的杂谈,有趣的历史 在过去的几十年中,独立于设备的输入输出模型得到了飞速的发展,标准C从这个改善的模型中 ...

  5. 走进C标准库(4)——"stdio.h"中的putc

    花了点时间把园子弄得好看了点,现在继续. 函数名: putc 功  能: 输出一字符到指定流中 用  法: int putc(int ch, FILE *stream); #define _putc_ ...

  6. 走进C标准库(5)——"stdio.h"中的其他部分函数

    函数介绍来自:http://ganquan.info/standard-c/ 函数名: freopen 功  能: 替换一个流 用  法: FILE *freopen(char *filename, ...

  7. 走进C标准库(1)——assert.h,ctype.h

    默默觉得原来的阅读笔记的名字太土了,改了个名字,叫做走进C标准库. 自己就是菜鸟一只,第一次具体看C标准库,文章参杂了对<the standard C library>的阅读和对源码的一些 ...

  8. 谈谈两种标准库类型---string和vector

    两种最重要的标准库---string和vector string和vector是两种最重要的标准库类型,string表示可变长的字符序列,vector存放的是某种给定类型对象的可变长序列. 一.标准库 ...

  9. C++ Primer 第三章 标准库类型string运算

    1. 标准库类型 string string表示可变长的字符序列,使用string必须首先包含string头文件.如何初始化类的对象是由类本身决定的. int n; string s1;//默认初始化 ...

随机推荐

  1. HasMap

    您还未登录 ! 登录 注册 论坛首页 → Java企业应用论坛 → 深入理解HashMap 全部 Hibernate Spring Struts iBATIS 企业应用 Lucene SOA Java ...

  2. Spring-----3、Spring的核心机制(依赖注入)

    转载自:http://blog.csdn.net/hekewangzi/article/details/41345237

  3. VC++客户端 缩小包的尺寸

    图片压缩: 1. 背景图片尺寸一般为100-300KB,使用纯色图片可缩小至1-3KB,方法得当可缩小1M多: 2. .ico一般为100-200KB,16x16一直到256x256,可减去其中几种尺 ...

  4. Android Bitmaps缓存

    Android 开发中,bitmap是引起内存泄漏的罪魁祸首,关于bitmap的加载,缓存策略,官方已经给了很详细的方法: 缓存之Memory Cache: 缓存的策略,是利用应用程序的分配的内存拿出 ...

  5. VS 对于LINK fatal Error 问题 解决方案

    方案1:    点击“项目”-->“属性” --> “清单工具”,    然后选择"输入和输出’ --> ‘嵌入清单’,将后面的‘是’改成‘否’就可以了 方案2: 在VS安 ...

  6. [Backbone.js]如何处理Model里面嵌入的Collection?

    写了近半个月的backbone.js代码,从一开始的todo到现在做仿微信的网页聊天,其中最大的困惑就在于如何处理比较复杂的Model,其内嵌了一个或者多个Collections. 假设我们有一个Pe ...

  7. JLINK烧写BIN文件到nand、norflash、SDRAM

    1. 简要说明 JLink的调试功能.烧写Flash的功能都很强大,但是对于S3C2410.S3C2440的Flash操作有些麻烦:烧写Nor Flash时需要设置SDRAM,否则速率很慢:烧写Nan ...

  8. Keil MDK中使用pc-lint的详细方法

    keil MDK版本:V4.03 PC-lint版本:  V8.0 关于pc-lint的强大作用,网上有很多,这里不想再复述,只说一句:能通过pc-lint检验的程序不一定没有问题,但通过了pc-li ...

  9. C语言入门(16)——C语言的数组

    和结构体类似,数组也是一种复合数据类型,它由一系列相同类型的元素组成.C语言支持一维数组和多维数组.如果一个数组的所有元素都不是数组,那么该数组称为一维数组. 一维数组的定义方式 在C语言中使用数组必 ...

  10. mongodb use db show dbs

    mongodb 常用命令: 在dbs间切换用 use xxxdb 之后再操作就是只针对 xxxdb了: show dbs显示全部数据库 show collections 显示全部集合 mongodb数 ...