strcmp为字符串比较函数,其函数原型为int strcmp( const char *str1, const char *str2 );
设有两个字符串为str1,str2,若str1=str2,则返回零;若str1< str2,则返回负数(一般为负1);若str1>str2,则返回正数(一般为正1)。 实际上比较的是字符的ASCII码。
思路:把两个字符串的字符(ASCII码)一个一个进行比较,当两个字符串不一样时,直接减,当两个字符串相等时,直接输出0。
代码:
//微软实现的strcmp源码
int my_strcmp(const char *str1,const char *str2)
{
//微软源码没有这两行assert,我想应该是将输入NULL的情况添加到异常中去了。不晓得
assert(str1);
assert(str2);
int ret=0;
while(!ret=(*str1-*str2)&&*str2)//判断*str1与*str2是否相等,而且*str2是不是为0,*str2为0,
//说明两个字符串相等
//我在vs2013是哪个输入strcmp(NULL,NULL),strcmp(NULL,str)都会报错。
//那么这儿的*str1还有*str2为0的情况应该是'\0'.
//如果*str2是'\0',对于逻辑与来说,!ret=(*str1-*str2)肯定是!0,即*str1=*str2,
//说明至少在'\0'之前的字符是相等的。可能出现\0充当字符串的情况,如"abc\0223"和"abc\02313",但是
//系统遇到\0就认为这个字符串结束,不会往后走。所以"abc\0223"和"abc\02313"认为就是abc和abc,所以
//是相等的。而如果*str1为0而*str2不为0,说明str1小于str2.此时,ret<0,所以!ret为0.此时不会进入while循环,
str1++,str2++;//字符相等才会进入while循环,字符串才会向后走,否则,如果碰到字符不相等,
//就直接看相应的字符的大小,如果小于则返回-1,大于则返回1,相等则返回ret,即就是while循环后的0.
//所以我感觉是首次碰到不相等的字符,比较这两个字符大小,有点像数学上的高位越大,数字越大。
比如:abc和edf,a是97,e是101,所以abc小于edf。
if ( ret < 0 )
ret = -1 ;
else if ( ret > 0 )
ret = 1 ;
return( ret );
}
glibc实现的strcmp函数
int STRCMP (const char *p1, const char *p2)
{
const unsigned char *s1 = (const unsigned char *) p1;//重新赋值指针,使其可以处理全部的字符
const unsigned char *s2 = (const unsigned char *) p2;//同上
unsigned char c1, c2;
do
{
c1 = (unsigned char) *s1++;//取出字符,并使指针后移
c2 = (unsigned char) *s2++;//同上
if (c1 == '\0')//如果字符c1为0,则直接返回差值。有三种情况:一,a\0 aa\0 此处返回。
//二,a\0 a\0 此处返回。aa\0 a\0 下面返回。
return c1 - c2;
}
while (c1 == c2);//如果字符相同,则继续循环。
return c1 - c2;//不相等则返回差值
}
我分析了下微软的,比较好写,所以面试的时候写微软的
还有一种是直接返回两者之间的差。而不是大于返回1,小于返回-1.
int strcmp(const char *str1, const char *str2) { while(*str1 && (*str1==*str2)){ ++str1; ++str2; } return *str1 - *str2; }