strcmp()如何工作?
我一直在四处寻找答案。 我要做一系列我自己的string函数,如my_strcmp()
, my_strcat()
等。
strcmp()
是否通过两个字符数组的每个索引,如果ASCII值在两个string的相同索引处较小,那么该string是按字母顺序排列的更大,因此返回0或1或2? 我猜我在问什么,是否使用字符的ASCII值来返回这些结果?
任何帮助将不胜感激。
[修订]
好的,所以我想出了这个…它适用于所有情况,除非第二个string大于第一个。
任何提示?
int my_strcmp(char s1[], char s2[]) { int i = 0; while ( s1[i] != '\0' ) { if( s2[i] == '\0' ) { return 1; } else if( s1[i] < s2[i] ) { return -1; } else if( s1[i] > s2[i] ) { return 1; } i++; } return 0; } int main (int argc, char *argv[]) { int result = my_strcmp(argv[1], argv[2]); printf("Value: %d \n", result); return 0; }
strcmp
的伪代码“实现”会像这样:
define strcmp (s1, s2): p1 = address of first character of str1 p2 = address of first character of str2 while contents of p1 not equal to null: if contents of p2 equal to null: return 1 if contents of p2 greater than contents of p1: return -1 if contents of p1 greater than contents of p2: return 1 advance p1 advance p2 if contents of p2 not equal to null: return -1 return 0
基本上就是这样。 每个字符依次进行比较,根据该字符判断第一个或第二个string是否较大。
只有当字符相同时,才会移动到下一个字符,如果所有字符都相同,则返回零。
请注意,您可能不一定会得到1和-1,规格说任何正值或负值都足够了,所以您应该始终用< 0
, > 0
或== 0
检查返回值。
把它变成真正的C将是相对简单的:
int myStrCmp (const char *s1, const char *s2) { const unsigned char *p1 = (const unsigned char *)s1; const unsigned char *p2 = (const unsigned char *)s2; while (*p1 != '\0') { if (*p2 == '\0') return 1; if (*p2 > *p1) return -1; if (*p1 > *p2) return 1; p1++; p2++; } if (*p2 != '\0') return -1; return 0; }
另外请记住,字符上下文中的“更大”不一定基于所有string函数的简单ASCIIsorting。
C有一个叫做“语言环境”的概念,指定(除其他之外)整理,或者对底层字符集的sorting,例如,你可能会发现字符a
, á
, à
和ä
被认为是相同的。 这将发生在像strcoll
这样的函数中。
这是BSD的实现 :
int strcmp(s1, s2) register const char *s1, *s2; { while (*s1 == *s2++) if (*s1++ == 0) return (0); return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1)); }
一旦两个字符之间不匹配,就会返回这两个字符之间的差异。
它使用字符的字节值,如果第一个string出现在第二个string之前(按字节值sorting),则返回负值,如果相等,则返回零;如果第一个string出现在第二个字符之后,则返回正值。 由于它使用字节操作,因此不支持编码。
例如:
strcmp("abc", "def") < 0 strcmp("abc", "abcd") < 0 // null character is less than 'd' strcmp("abc", "ABC") > 0 // 'a' > 'A' in ASCII strcmp("abc", "abc") == 0
更确切地说,如strcmp Open Group规范中所述 :
非零返回值的符号应由第一对字节(两者解释为types无符号字符)的值之间的差异的符号确定,所述字符在被比较的string中不同。
请注意,返回值可能不等于这个差异,但它将带有相同的符号。
这从主人自己( K&R ,第二版,第106页):
// strcmp: return < 0 if s < t, 0 if s == t, > 0 if s > t int strcmp(char *s, char *t) { int i; for (i = 0; s[i] == t[i]; i++) if (s[i] == '\0') return 0; return s[i] - t[i]; }
这是我的版本,为小型微控制器应用程序,MISRA-C兼容写的。 这个代码的主要目的是编写可读的代码,而不是在大多数编译器库中find的单行代码。
int8_t strcmp (const uint8_t* s1, const uint8_t* s2) { while ( (*s1 != '\0') && (*s1 == *s2) ) { s1++; s2++; } return (int8_t)( (int16_t)*s1 - (int16_t)*s2 ); }
注意:代码假定16位int
types。
这段代码是相当的,更短,更可读:
int8_t strcmp (const uint8_t* s1, const uint8_t* s2) { while( (*s1!='\0') && (*s1==*s2) ){ s1++; s2++; } return (int8_t)*s1 - (int8_t)*s2; }
我们只需要testings1的结束,因为如果在s1结束之前到达s2的末尾,循环将终止(因为* s2!= * s1)。
如果我们只使用7位(纯ASCII)字符,则返回expression式会在每种情况下计算正确的值。 由于整数溢出的危险,需要仔细考虑为8位字符生成正确的代码。
我在网上find了这个。
http://www.opensource.apple.com/source/Libc/Libc-262/ppc/gen/strcmp.c
int strcmp(const char *s1, const char *s2) { for ( ; *s1 == *s2; s1++, s2++) if (*s1 == '\0') return 0; return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : +1); }
这是我如何实现我的strcmp:它是这样工作的:它比较两个string的第一个字母,如果它是相同的,它继续下一个字母。 如果不是,则返回相应的值。 这很简单易懂:#include
//function declaration: int strcmp(char string1[], char string2[]); int main() { char string1[]=" The San Antonio spurs"; char string2[]=" will be champins again!"; //calling the function- strcmp printf("\n number returned by the strcmp function: %d", strcmp(string1, string2)); getch(); return(0); } /**This function calculates the dictionary value of the string and compares it to another string. it returns a number bigger than 0 if the first string is bigger than the second it returns a number smaller than 0 if the second string is bigger than the first input: string1, string2 output: value- can be 1, 0 or -1 according to the case*/ int strcmp(char string1[], char string2[]) { int i=0; int value=2; //this initialization value could be any number but the numbers that can be returned by the function while(value==2) { if (string1[i]>string2[i]) { value=1; } else if (string1[i]<string2[i]) { value=-1; } else { i++; } } return(value); }
就是这样:
int strcmp(char *str1, char *str2){ while( (*str1 == *str2) && (*str1 != 0) ){ ++*str1; ++*str2; } return (*str1-*str2); }
如果你想要更快,你可以在input之前加上“register”,像这样:register char
那么,像这样:
int strcmp(register char *str1, register char *str2){ while( (*str1 == *str2) && (*str1 != 0) ){ ++*str1; ++*str2; } return (*str1-*str2); }
这样,如果可能的话,使用ALU的寄存器。