C语言strncmp返回1的原因及自定义实现逻辑疑问
关于strncmp返回值及自定义实现的疑问
我尝试用原生C语言实现自定义strncmp函数,随后进行了如下测试:
#include <string.h> #include <stdio.h> printf("%d\n", strncmp("test\200", "test\0", 6));
在该测试场景中,strncmp的返回值为1,请问有人能解释其中原因吗?我猜测这是因为\200超出了默认ASCII范围,于是在自定义实现中添加了条件:若字符不在0-127范围内则返回1,这样的处理是否正确?
原因解释
- 核心比较逻辑:
strncmp会把字符当作unsigned char逐字节比较。\200是八进制转义字符,对应十进制值128;\0的十进制值是0。当比较到第五个字符时,128的无符号值大于0,因此strncmp返回正整数(这里为1,具体数值由实现决定,但必然为正)。 - 与ASCII范围无关:返回1的本质是两个字符的数值差,和是否超出ASCII范围没有关系。比如用
'a'(十进制97)和'\0'比较,strncmp同样会返回正数。
自定义实现的问题
你添加的“字符不在0-127范围内则返回1”的逻辑完全不符合strncmp的标准行为:
strncmp是逐字节对比,仅当对应位置字符不同时,返回两者无符号值的差值符号;若前n个字符完全相同,则返回0。- 举例:对比
"test\200"和"test\201"时,你的逻辑会直接返回1,但标准strncmp会返回-1(因为128 < 129);对比"test\177"(十进制127)和"test\200"时,你的逻辑返回1,但标准实现会返回-1。
正确的自定义strncmp实现思路
标准逻辑应遵循以下规则:
- 循环对比两个字符串的前
n个字符,每次将字符转换为unsigned char后比较。 - 若某位置字符不同,返回
(unsigned char)s1[i] - (unsigned char)s2[i]对应的正负整数或0。 - 若循环完
n个字符或遇到'\0'(后续均为'\0'),则返回0。
简化实现示例:
int my_strncmp(const char *s1, const char *s2, size_t n) { while (n-- > 0) { unsigned char c1 = (unsigned char)*s1; unsigned char c2 = (unsigned char)*s2; if (c1 != c2) { return c1 - c2; } if (c1 == '\0') { break; } s1++; s2++; } return 0; }
内容的提问来源于stack exchange,提问作者fabinfabinfabin
相关产品推荐
相关产品推荐

