模拟strcmp函数返回值异常:返回101/-101而非1/-1求助
问题:模拟strcmp()函数时返回值不符合预期
教授布置作业要求实现一个完全模拟strcmp()的函数,且不能使用任何库函数。编写代码后发现,当其中一个字符串更长时,函数返回101和-101,而非预期的1和-1。
用户代码
#include <stdio.h> int string_compare(char v[], char w[]) { int sizeV = sizeof(v) / sizeof(v[0]); int sizeW = sizeof(w) / sizeof(w[0]); if(sizeV == sizeW) { int i; int x = 0; for(i = 0; i < sizeV; i++) { if(v[i] != w[i]) { x = v[i] - w[i]; break; } } return x; } else return (sizeV > sizeW)? 1 : -1; } int main(void) { printf("'abcd', 'abcD': %d", string_compare("abcd", "abcD")); printf("\n'abcd', 'abcde': %d", string_compare("abcd", "abcde")); printf("\n'abcde', 'abcd': %d", string_compare("abcde", "abcd")); printf("\n'', '': %d", string_compare("", "")); printf("\n'abcd', 'abcd': %d", string_compare("abcd", "abcd")); return 0; }
运行输出
'abcd', 'abcD': 32 'abcd', 'abcde': -101 'abcde', 'abcd': 101 '', '': 0 'abcd', 'abcd': 0
问题原因
核心错误是用sizeof计算字符串长度的方式完全错误:当字符串作为参数传递给函数时,char v[]会退化为char*指针,此时sizeof(v)得到的是指针的大小(32位系统为4,64位系统为8),而非字符串的实际长度。你看到的101/-101是错误计算的"长度"差值,和字符串本身毫无关系。
另外,你的逻辑完全不符合标准strcmp()的规则:标准strcmp()不会先比较长度,而是逐字符比较,直到遇到不同字符或到达字符串末尾('\0'):
- 若所有字符相同,较短的字符串更小;
- 若遇到不同字符,返回第一个不同字符的ASCII差值;
- 完全相同则返回0。
修正后的代码
#include <stdio.h> int string_compare(const char *v, const char *w) { // 逐字符遍历,直到出现差异或字符串结束 while (*v != '\0' && *w != '\0' && *v == *w) { v++; w++; } // 返回当前字符的差值,自动处理长度不同的情况 return (*v - *w); } int main(void) { printf("'abcd', 'abcD': %d\n", string_compare("abcd", "abcD")); printf("'abcd', 'abcde': %d\n", string_compare("abcd", "abcde")); printf("'abcde', 'abcd': %d\n", string_compare("abcde", "abcd")); printf("'', '': %d\n", string_compare("", "")); printf("'abcd', 'abcd': %d\n", string_compare("abcd", "abcd")); return 0; }
代码说明
- 使用指针遍历字符串,避免数组退化导致的长度计算错误;
- 严格遵循
strcmp()的原生逻辑,逐字符比较直到出现差异或结束; - 最终返回当前字符的差值:若一个字符串先结束,其当前字符为'\0'(ASCII值0),差值即为另一个字符串当前字符的ASCII值,符合标准行为;
- 参数使用
const char*,明确字符串只读特性,代码更严谨。
内容的提问来源于stack exchange,提问作者Nebelmonster
相关产品推荐
相关产品推荐

