strcmp 的实现
Implementation of strcmp
我尝试实现 strcmp
:
int strCmp(char string1[], char string2[])
{
int i = 0, flag = 0;
while (flag == 0) {
if (string1[i] > string2[i]) {
flag = 1;
} else
if (string1[i] < string2[i]) {
flag = -1;
} else {
i++;
}
}
return flag;
}
但我坚持用户将输入相同字符串的情况,因为该函数适用于 1
和 -1
,但它不适用于 return 0
。谁能帮忙?还请指点!
嗯..太复杂了。选择这个:
int strCmp(const char* s1, const char* s2)
{
while(*s1 && (*s1 == *s2))
{
s1++;
s2++;
}
return *(const unsigned char*)s1 - *(const unsigned char*)s2;
}
它 returns <0、0 或 >0 符合预期
没有指点是做不到的。在 C 中,索引数组 是 使用指针。
也许您想避免使用 *
运算符? :-)
您的问题是您没有检测到字符串的结尾,因此如果两个字符串在检测到任何差异之前结束,则不会 return 为零。
您可以通过在循环条件中检查这一点来简单地解决此问题:
while( flag==0 && (string1[i] != 0 | string2[i] != 0 ) )
请注意,两个字符串都会被检查,因为如果最后只有一个字符串,则字符串不相等,循环内的比较应该检测到这一点。
请注意,字符比较可能不会产生您预期的结果。一方面,它没有定义 char
是有符号的还是无符号的,因此您可能应该转换为 unsigned char
进行比较。
也许更简洁的解决方案是当您检测到差异时立即 return,即直接 return -1
而不是 flag = -1
。但这更见仁见智。
首先,标准 C 函数 strcmp
比较字符串元素的类型 unsigned char
。
其次,参数应该是指向常量字符串的指针,以便也为常量字符串提供比较。
函数可以这样写
int strCmp( const char *s1, const char *s2 )
{
const unsigned char *p1 = ( const unsigned char * )s1;
const unsigned char *p2 = ( const unsigned char * )s2;
while ( *p1 && *p1 == *p2 ) ++p1, ++p2;
return ( *p1 > *p2 ) - ( *p2 > *p1 );
}
您似乎想避免指针算法,这很遗憾,因为这会使解决方案更短,但您的问题只是您扫描到字符串末尾之外。添加显式中断将起作用。您的程序稍作修改:
int strCmp(char string1[], char string2[] )
{
int i = 0;
int flag = 0;
while (flag == 0)
{
if (string1[i] > string2[i])
{
flag = 1;
}
else if (string1[i] < string2[i])
{
flag = -1;
}
if (string1[i] == '[=10=]')
{
break;
}
i++;
}
return flag;
}
更短的版本:
int strCmp(char string1[], char string2[] )
{
for (int i = 0; ; i++)
{
if (string1[i] != string2[i])
{
return string1[i] < string2[i] ? -1 : 1;
}
if (string1[i] == '[=11=]')
{
return 0;
}
}
}
摘自 here.
#include<stdio.h>
#include<string.h>
//using arrays , need to move the string using index
int strcmp_arry(char *src1, char *src2)
{
int i=0;
while((src1[i]!='[=10=]') || (src2[i]!='[=10=]'))
{
if(src1[i] > src2[i])
return 1;
if(src1[i] < src2[i])
return -1;
i++;
}
return 0;
}
//using pointers, need to move the position of the pointer
int strcmp_ptr(char *src1, char *src2)
{
int i=0;
while((*src1!='[=10=]') || (*src2!='[=10=]'))
{
if(*src1 > *src2)
return 1;
if(*src1 < *src2)
return -1;
src1++;
src2++;
}
return 0;
}
int main(void)
{
char amessage[] = "string";
char bmessage[] = "string1";
printf(" value is %d\n",strcmp_arry(amessage,bmessage));
printf(" value is %d\n",strcmp_ptr(amessage,bmessage));
}
我做了一些更改,使其像 strcmp
一样工作。
这是 strcmp 的 10 个操作码实现(假定为 GCC)
int strcmp_refactored(const char *s1, const char *s2)
{
while (1)
{
int res = ((*s1 == 0) || (*s1 != *s2));
if (__builtin_expect((res),0))
{
break;
}
++s1;
++s2;
}
return (*s1 - *s2);
}
您可以尝试这个实现并与其他实现进行比较https://godbolt.org/g/ZbMmYM
我的实现
int strcmp(const char * s1, const char * s2)
{
while (*s1 == *s2 && *s1++ | *s2++);
int i = *s1 - *s2;
return i < 0 ? -1 : i > 0 ? 1 : 0;
}
return 值
-1 // <0
1 // >0
0 // ==0
The last ternary operation is optional
当您 return *s1 - *s2
.
时,该功能仍将遵循 strcmp
的规则
另一个优雅的(但不是最“干净的代码”)实现,带有指针。
int a_strcmp(char* t, char* s)
{
for( ; *t == *s ; *s++ , *t++)
if(*t == '[=10=]')
return 0;
return *t - *s;
}
不使用指针的版本。
int b_strcmp(char t[], char s[])
{
int i;
for(i = 0; s[i] == t[i]; ++i)
if(t[i] == '[=11=]')
return 0;
return t[i] - s[i];
}
我尝试实现 strcmp
:
int strCmp(char string1[], char string2[])
{
int i = 0, flag = 0;
while (flag == 0) {
if (string1[i] > string2[i]) {
flag = 1;
} else
if (string1[i] < string2[i]) {
flag = -1;
} else {
i++;
}
}
return flag;
}
但我坚持用户将输入相同字符串的情况,因为该函数适用于 1
和 -1
,但它不适用于 return 0
。谁能帮忙?还请指点!
嗯..太复杂了。选择这个:
int strCmp(const char* s1, const char* s2)
{
while(*s1 && (*s1 == *s2))
{
s1++;
s2++;
}
return *(const unsigned char*)s1 - *(const unsigned char*)s2;
}
它 returns <0、0 或 >0 符合预期
没有指点是做不到的。在 C 中,索引数组 是 使用指针。
也许您想避免使用 *
运算符? :-)
您的问题是您没有检测到字符串的结尾,因此如果两个字符串在检测到任何差异之前结束,则不会 return 为零。
您可以通过在循环条件中检查这一点来简单地解决此问题:
while( flag==0 && (string1[i] != 0 | string2[i] != 0 ) )
请注意,两个字符串都会被检查,因为如果最后只有一个字符串,则字符串不相等,循环内的比较应该检测到这一点。
请注意,字符比较可能不会产生您预期的结果。一方面,它没有定义 char
是有符号的还是无符号的,因此您可能应该转换为 unsigned char
进行比较。
也许更简洁的解决方案是当您检测到差异时立即 return,即直接 return -1
而不是 flag = -1
。但这更见仁见智。
首先,标准 C 函数 strcmp
比较字符串元素的类型 unsigned char
。
其次,参数应该是指向常量字符串的指针,以便也为常量字符串提供比较。
函数可以这样写
int strCmp( const char *s1, const char *s2 )
{
const unsigned char *p1 = ( const unsigned char * )s1;
const unsigned char *p2 = ( const unsigned char * )s2;
while ( *p1 && *p1 == *p2 ) ++p1, ++p2;
return ( *p1 > *p2 ) - ( *p2 > *p1 );
}
您似乎想避免指针算法,这很遗憾,因为这会使解决方案更短,但您的问题只是您扫描到字符串末尾之外。添加显式中断将起作用。您的程序稍作修改:
int strCmp(char string1[], char string2[] )
{
int i = 0;
int flag = 0;
while (flag == 0)
{
if (string1[i] > string2[i])
{
flag = 1;
}
else if (string1[i] < string2[i])
{
flag = -1;
}
if (string1[i] == '[=10=]')
{
break;
}
i++;
}
return flag;
}
更短的版本:
int strCmp(char string1[], char string2[] )
{
for (int i = 0; ; i++)
{
if (string1[i] != string2[i])
{
return string1[i] < string2[i] ? -1 : 1;
}
if (string1[i] == '[=11=]')
{
return 0;
}
}
}
摘自 here.
#include<stdio.h>
#include<string.h>
//using arrays , need to move the string using index
int strcmp_arry(char *src1, char *src2)
{
int i=0;
while((src1[i]!='[=10=]') || (src2[i]!='[=10=]'))
{
if(src1[i] > src2[i])
return 1;
if(src1[i] < src2[i])
return -1;
i++;
}
return 0;
}
//using pointers, need to move the position of the pointer
int strcmp_ptr(char *src1, char *src2)
{
int i=0;
while((*src1!='[=10=]') || (*src2!='[=10=]'))
{
if(*src1 > *src2)
return 1;
if(*src1 < *src2)
return -1;
src1++;
src2++;
}
return 0;
}
int main(void)
{
char amessage[] = "string";
char bmessage[] = "string1";
printf(" value is %d\n",strcmp_arry(amessage,bmessage));
printf(" value is %d\n",strcmp_ptr(amessage,bmessage));
}
我做了一些更改,使其像 strcmp
一样工作。
这是 strcmp 的 10 个操作码实现(假定为 GCC)
int strcmp_refactored(const char *s1, const char *s2)
{
while (1)
{
int res = ((*s1 == 0) || (*s1 != *s2));
if (__builtin_expect((res),0))
{
break;
}
++s1;
++s2;
}
return (*s1 - *s2);
}
您可以尝试这个实现并与其他实现进行比较https://godbolt.org/g/ZbMmYM
我的实现
int strcmp(const char * s1, const char * s2)
{
while (*s1 == *s2 && *s1++ | *s2++);
int i = *s1 - *s2;
return i < 0 ? -1 : i > 0 ? 1 : 0;
}
return 值
-1 // <0
1 // >0
0 // ==0
The last ternary operation is optional
当您 return *s1 - *s2
.
strcmp
的规则
另一个优雅的(但不是最“干净的代码”)实现,带有指针。
int a_strcmp(char* t, char* s)
{
for( ; *t == *s ; *s++ , *t++)
if(*t == '[=10=]')
return 0;
return *t - *s;
}
不使用指针的版本。
int b_strcmp(char t[], char s[])
{
int i;
for(i = 0; s[i] == t[i]; ++i)
if(t[i] == '[=11=]')
return 0;
return t[i] - s[i];
}