strcmp核心是逐字节比较:先转unsigned char再相减,避免有符号溢出;循环中先判等再检\0,防止越界;需正确处理空字符串、不等长及内容差异场景。

strcmp 的核心逻辑其实是逐字节比较
标准 strcmp 不是靠计算长度或哈希,而是从首字节开始,一个一个比,遇到不同就立刻返回差值,遇到 \0 就停。手动实现时最容易错的是忽略「提前终止」和「有符号字符溢出」——比如用 char 直接相减,当字符值 >127 时会变成负数,导致差值符号错误。
正确做法是把每个字节先转成 unsigned char,再转 int 做减法:
int my_strcmp(const char* s1, const char* s2) {
while (*s1 == *s2) {
if (*s1 == '\0') return 0;
s1++;
s2++;
}
return (unsigned char)*s1 - (unsigned char)*s2;
}为什么不能直接用 char 相减
因为 char 在不同平台可能是有符号或无符号,默认行为不一致。例如在 GCC x86_64 上,char 是 signed,'\xFF'(即 255)会被解释为 -1,-1 - 0 得 -1,但实际应该返回正数(255 - 0 = 255)。
- 错误写法:
return *s1 - *s2→ 可能返回错误符号 - 正确写法:
return (unsigned char)*s1 - (unsigned char)*s2 - 注意:两个
unsigned char相减结果自动提升为int,不会溢出
边界情况必须覆盖这三种
手动实现时容易漏掉空指针、等长但内容不同、以及一方提前结束的组合。标准 strcmp 要求:空指针行为未定义,所以实现里不主动检查;但你要确保逻辑能自然处理以下场景:
立即学习“C++免费学习笔记(深入)”;
-
my_strcmp("abc", "abc")→ 返回 0 -
my_strcmp("ab", "abc")→ 在第三个位置:'\0' vs 'c' → 返回负值 -
my_strcmp("abc", "ab")→ 同理,返回正值
关键点在于:循环体里先判相等,再检查是否到结尾,顺序不能反,否则会读越界。
性能上没必要自己优化,但要注意内联和 const
现代编译器对这种简单循环优化极好,手动加 __attribute__((always_inline)) 或 inline 几乎没差别;但参数一定要声明为 const char*,否则调用时传入字符串字面量(如 "hello")会触发编译警告(丢弃 const 限定)。
另外,别试图用 SIMD 或一次读 4 字节来“加速”——标准库实现确实这么干,但需要处理对齐、剩余字节、大小端,复杂度陡增,且对短字符串反而更慢。
真正容易被忽略的是:你写的这个函数,如果和系统 strcmp 同名又没加 static,链接时可能被静默替换,调试时行为诡异。建议起名 my_strcmp 或加命名空间封装。


















