我的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. mysql 存在该记录则更新,不存在则插入记录的sql

    转 http://www.cnblogs.com/zeroone/articles/2298929.html , ‘yourname') ON DUPLICATE KEY UPDATE auto_na ...

  2. JavaScript判断IE各版本完美解决方案

    解决方案 IE知道自身毛病很多,于是提供的一套官方的HTML hack方式: <!--[if IE]> // 全部IE版本可见 <![endif]--> <!--[if ...

  3. JavaScript总结之鼠标划过弹出div单击出现对话框

    为了满足他们的永无止境的要求,我可谓是任劳任怨啊,累断了双手,看瞎了双眼.这个是来写鼠标划过一个按钮,然后弹出一个小提示框解释,另外根据radio是否选中,判断点击后如何执行,然后执行之后再有一个确认 ...

  4. Messenger类的使用

    一.Messenger类 作用:类似Message类,但是是跨进程使用的. 解析:它的底层是由AIDL实现的,从构造方法可以看出 //Service使用 public Messenger(Handle ...

  5. [Backbone.js]如何用backbone写一个仿网页版微信的webapp?

    var Chat = Backbone.Model.extend({ idAttribute:'id', initialize:function(options){ var users = this. ...

  6. Cortex-M3和Cortex-M4 Fault异常应用之二 ----- Fault处理函数的实现

    在项目处于调试期间,Fault处理程序可能只是一个断点指令,调试器遇到这个指令后停止程序的运行.默认情况下,由于非硬Fault被禁能,所有发生的非Fault都会上访成硬Fault,因此只要在硬Faul ...

  7. 迁移到MSYS2 与 Qt 工具链注意的几个事情(注意链接顺序,并且人造mingw工具链所没有的局部midl.exe命令)

    Microsoft Visual Studio 2015社区版提供了强大的开发体验,且 Qt 提供了预编译版本.然而,由于客户提出兼容Windows XP ~ Windows 8.1 这样宽泛的环境要 ...

  8. ListFragment和ListActivity的setOnItemClickListener不起作用

    在使用ListFragment时,发现一个奇怪的问题,就是getListView().setOnItemClickListener(new OnItemClickListener...)不起作用.在s ...

  9. rsyslog 读日志文件 ,当rsyslog 中断时,也会丢数据

    rsyslog 日志服务器: [root@dr-mysql01 winfae_log]# grep scan0819 wj-proxy01-catalina.out.2016-08-19 [root@ ...

  10. xxx.java: Recompile with -Xlint:deprecation for details

    警告而已.有些方法1 已经过时,有更好的方法可以代替,比如 new java.util.Date().getYear(); => cal.get(Calendar.YEAR);2 发现过问题,且 ...