走进C标准库(7)——"string.h"中函数的实现memcmp,memcpy,memmove,memset
我的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的更多相关文章
- 走进C标准库(8)——"string.h"中函数的实现相关字符串操作函数
我的strcat: char *strcat(char *dest,char *src) { char * reval = dest; while(*dest) dest++; while(*src) ...
- 走进C标准库(6)——"string.h"中函数的实现memchr
我写的memchr: void *memchr(const void *buf, char ch, unsigned count){ unsigned ; while(*(buf++) != ch & ...
- 走进C标准库(3)——"stdio.h"中的getc和ungetc
接前文. 再来看看getc和ungetc的实现.在看这两个函数的实现之前,我们先来想一想这两个函数分别需要做的工作. int getc(FILE *stream) 说明:函数getc从stream指向 ...
- 走进C标准库(2)——"stdio.h"中的fopen函数
其他的库文件看起来没有什么实现层面的知识可以探究的,所以,直接来看stdio.h. 1.茶余饭后的杂谈,有趣的历史 在过去的几十年中,独立于设备的输入输出模型得到了飞速的发展,标准C从这个改善的模型中 ...
- 走进C标准库(4)——"stdio.h"中的putc
花了点时间把园子弄得好看了点,现在继续. 函数名: putc 功 能: 输出一字符到指定流中 用 法: int putc(int ch, FILE *stream); #define _putc_ ...
- 走进C标准库(5)——"stdio.h"中的其他部分函数
函数介绍来自:http://ganquan.info/standard-c/ 函数名: freopen 功 能: 替换一个流 用 法: FILE *freopen(char *filename, ...
- 走进C标准库(1)——assert.h,ctype.h
默默觉得原来的阅读笔记的名字太土了,改了个名字,叫做走进C标准库. 自己就是菜鸟一只,第一次具体看C标准库,文章参杂了对<the standard C library>的阅读和对源码的一些 ...
- 谈谈两种标准库类型---string和vector
两种最重要的标准库---string和vector string和vector是两种最重要的标准库类型,string表示可变长的字符序列,vector存放的是某种给定类型对象的可变长序列. 一.标准库 ...
- C++ Primer 第三章 标准库类型string运算
1. 标准库类型 string string表示可变长的字符序列,使用string必须首先包含string头文件.如何初始化类的对象是由类本身决定的. int n; string s1;//默认初始化 ...
随机推荐
- SQL Server 事务嵌套
示例代码: DECLARE @TranCounter INT; SET @TranCounter = @@TRANCOUNT; -- Procedure called when there is -- ...
- java总结
JUC概况 以下是Java JUC包的主体结构: ? Atomic : AtomicInteger ? Locks : Lock, Condition, ReadWriteLock ? Collect ...
- [Tree]Binary Tree Preorder Traversal
Total Accepted: 97599 Total Submissions: 257736 Difficulty: Medium Given a binary tree, return the p ...
- Linux编程C/C++
C/C++基本数据类型 C/C++语言有一组基本数据类型,对应于计算机的基本存储单元和使用这些单元去保存数据的一些常用方式. 基本数据类型如下: 上面表格中的类型是基本的C/C++数据类型,但是在C+ ...
- java后台获取国际化资源文件
//current属性,由于此属性只做赋值操作,不做取值操作,因此没有get方法 private Locale current; public void setCurrent(Locale cur) ...
- zend studio 使用断点调试
1, 下载 Xdebug 1 # 下载地址 2 # http://xdebug.org/download.php 3 4 # 寻找和自己所安装的 php 版本对应的 Xdebug 下载 5 # 对 ...
- Android APN配置
APN概念 APN(Access Point Name),即“接入点名称”,用来标识GPRS的业务种类,目前分为两大类:CMWAP(通过GPRS访问WAP业务).CMNET(除了WAP以外的服务目前都 ...
- 新装docker 从本地仓库下载
docker:/root# docker images Get http:///var/run/docker.sock/v1.19/images/json: dial unix /var/run/do ...
- 加入商品分类信息,考虑用户所处阶段的 图模型 推荐算法 Rws(random walk with stage)
场景: 一个新妈妈给刚出生的宝宝买用品,随着宝宝的长大,不同的阶段需要不同的物品. 这个场景中涉及到考虑用户所处阶段,给用户推荐物品的问题. 如果使用用户协同过滤,则需要根据购买记录,找到与用户处于同 ...
- Python学习笔记3-文件的简单操作
Python中的文件操作 Python中文件打操作离不开两个模块 os 和 shutil os:操作文件.目录: Python os模块包含普遍的操作系统功能.如果你希望你的程序能够与平台无关的话, ...