1.C库中strcmp的实现代码
方法1:
int strcmp(char *str1,char *str2)
{
for(;*str1==*str2;str1++,str2++)
{
if(*str1=='\0')
return 0;
}
return (*(unsigned char *)str1<*(unsigned char *)str2 ?-1:1);
}
为什么使用unsigned char呢?这是因为char的表示范围是-128~127,unsigned char的表示范围是0~255。如果不使用unsigned char的话,传入ASCII不会出现问题,但是若传入扩展ASCII码会出现问题。
字符串其实就是字符数组(最后一个字符为‘\0’),所以字符串”hello”<”helloworld”,
方法2:
int strcmp(char *str1,char *str2)
{
assert((str1!=NULL)&&(str2!=NULL));
int ret=0;
while(!(ret!=*(unsigned char*)str1-*(unsigned char*)str2) && *str2)
{
str1++;
str2++;
}
if(ret>0)
ret=1;
else if(ret<0)
ret=-1;
return ret;
}
2.C 语言库函数strcpy的实现
char *strcpy(char *strDest,char *strSrc)
{
assert((strDest!=NULL) && (strSrc!=NULL));
char *address=strDest;
while((*strDest++=*strSrc++)!=’\0’);
return address;
}
3.内存拷贝函数memcpy
需注意的是:按照ANSI(American National Standards Institute)标准,不能对void指针进行算法操作,即不能对void指针进行如p++的操作,所以需要转换为具体的类型指针来操作,例如char *。
void * memcpy(void *pTo,const void *pFrom,size_t count)
{
//memcpy函数没有处理pTo和pFrom所指内存区域是否重叠的问题
void *ret=pTo;
while(count--)
{
*(char *)pTo=*(char *)pFrom;
pTo=(char *)pTo+1;
pFrom=(char *)pFrom+1;
}
return ret;
}
4.内存操作memmove函数
void* memcpy(void *pTo,const void *pFrom,size_t size)
{
if(pTo==NULL || pFrom==NULL)
return ;
void *ret=pTo;
//没有内存重叠,从低地址开始复制
if(pTo <=pFrom ||(char*)pTo >=(char *)pFrom +size)
{
while(size--)
{
*(char *)pTo=*(char *)pFrom;
pTo=(char *)pTo+1;
pFrom=(char *)pFrom+1;
}
}
else//有内存重叠,从高地址开始复制
{
pFrom=(char *)pFrom +size-1;
pTo=(char *)pTo +size-1;
while(size--)
{
*(char *)pTo=*(char *)pFrom;
pTo=(char *)pTo-1;
pFrom=(char *)pFrom-1;
}
}
return ret;
}
从程序可以看出当pTo和pFrom所指区域没有重叠时,两个函数时完全一样的,内存没有重叠的条件是:pTo<=pFrom ||(char )pTo>=(char )pFrom+size.否则,memcpy是不能正常工作的,而memmove是可以正常工作的