自定义string_compare(复刻strcmp)函数输出异常,求原因
自定义strcmp函数输出不符合预期问题分析
问题重现
你尝试复刻string.h中的strcmp()函数,实现了string_compare函数:
/** * string_compare - this function compares two strings pointed * by s1 and s2. Is a replica of the strcmp from the string.h library * @s1: The first string to be compared * @s2: The second string to be compared * * Return: On success, it returns: * 0 if s1 is equal to s2 * negative value if s1 is less that s2 * positive value if s1 is greater than s2 */ int string_compare(char *s1, char *s2) { int sum = 0, i; for (i = 0; s1[i] != '\0' && s2[i] != '\0'; i++) sum += (s1[i] - s2[i]); for ( ; s1[i] != '\0'; i++) sum += (s1[i] - 0); for ( ; s2[i] != '\0'; i++) sum += (0 - s2[i]); return (sum); }
测试代码:
#include <stdio.h> int main(void) { char s1[] = "Hello"; char s2[] = "World!"; printf("%d\n", string_compare(s1, s2)); printf("%d\n", string_compare(s2, s1)); printf("%d\n", string_compare(s1, s1)); return (0); }
实际输出:
-53 -500 0
预期输出:
-15 15 0
错误原因
你的string_compare函数逻辑完全偏离了标准strcmp的设计:
标准strcmp的核心是返回第一个不同字符的ASCII差值,一旦找到第一个不相等的字符,立即返回该差值,不会继续计算后续字符。而你的代码是把所有字符的差值累加,还额外加上了其中一个字符串剩余字符的ASCII值(或其负值),这就导致结果变成了所有字符差值的总和,而非第一个不同字符的差值。
比如测试用例中,"Hello"和"World!"的第一个不同字符是'H'(ASCII 72)和'W'(ASCII 87),标准strcmp会直接返回72-87=-15,但你的代码会把所有对应位置的差值(H-W, e-o, l-r, l-l, o-d)以及s2中剩余的'!'的负值累加,最终得到和预期完全不符的总和。
正确实现
要复刻标准strcmp,应该在遍历过程中找到第一个不同的字符,直接返回差值;若所有前面的字符都相同,则返回两个字符串当前位置的差值(此时其中一个字符串已到结尾,即'\0',差值就是剩余字符的ASCII值):
int string_compare(char *s1, char *s2) { int i = 0; // 遍历直到遇到不同字符或任一字符串结束 while (s1[i] != '\0' && s2[i] != '\0' && s1[i] == s2[i]) { i++; } // 返回第一个不同字符的差值,或末尾的差值 return s1[i] - s2[i]; }
使用这个实现运行测试代码,会得到预期的输出:-15、15、0,完全符合标准strcmp的行为。
内容的提问来源于stack exchange,提问作者Leuel Asfaw
相关产品推荐
相关产品推荐

