strcmp/strncmp源码分析
来源:互联网 发布:单片机常用芯片 编辑:程序博客网 时间:2024/05/20 18:45
1. strcmp
strcmp 用于比较两个字符串是否相等。内部实现与我们最初的想法一致,就是循环遍历两个字符串,遇到不相等的那一位即返回差值。
intstrcmp (p1, p2) const char *p1; const char *p2;{ register const unsigned char *s1 = (const unsigned char *) p1; register const unsigned char *s2 = (const unsigned char *) p2; unsigned char c1, c2; do { c1 = (unsigned char) *s1++; c2 = (unsigned char) *s2++; if (c1 == '\0')return c1 - c2; } while (c1 == c2); return c1 - c2;}这里用到了 register 修饰符。register 修饰符意思是将此变量的值存放到寄存器中。除此之外,也没做别的特殊优化。
2. strncmp
此函数功能与 strcmp 类似,也是比较两个字符串的大小,不同的是只比较前 n 个字符,相对于之前的版本来说更加安全。
对于此函数,最简单的想法就是按字符逐个比较,直到遇到字符串结束。
while (n > 0){ c1 = (unsigned char) *s1++; c2 = (unsigned char) *s2++; if (c1 == '\0' || c1 != c2) return c1 - c2; n--;}
以下是 strncmp 的 glibc 的实现。
/* Compare no more than N characters of S1 and S2, returning less than, equal to or greater than zero if S1 is lexicographically less than, equal to or greater than S2. */intstrncmp (const char *s1, const char *s2, size_t n){ unsigned char c1 = '\0'; unsigned char c2 = '\0'; if (n >= 4) { size_t n4 = n >> 2; do{ c1 = (unsigned char) *s1++; c2 = (unsigned char) *s2++; if (c1 == '\0' || c1 != c2) return c1 - c2; c1 = (unsigned char) *s1++; c2 = (unsigned char) *s2++; if (c1 == '\0' || c1 != c2) return c1 - c2; c1 = (unsigned char) *s1++; c2 = (unsigned char) *s2++; if (c1 == '\0' || c1 != c2) return c1 - c2; c1 = (unsigned char) *s1++; c2 = (unsigned char) *s2++; if (c1 == '\0' || c1 != c2) return c1 - c2;} while (--n4 > 0); n &= 3; } while (n > 0) { c1 = (unsigned char) *s1++; c2 = (unsigned char) *s2++; if (c1 == '\0' || c1 != c2)return c1 - c2; n--; } return c1 - c2;}
算法的重点在那个大大的 “do” 循环里面。明明一个小循环就能搞定的,为什么要把同样的四行代码 copy 四遍呢?
这应该与CPU处理器进行流水线操作时的分支预测有关系,这么做可以让其每四次才经历一次分支预测。下表是两个函数分别运行 10w 次的运行结果。
从上表可以看出,对于预测流水线的优化有一定效果,但是优化效果在10%~20%左右。
- strcmp/strncmp源码分析
- strcmp() , strncmp();
- strcmp 与strncmp
- strcmp与strncmp区别
- strcmp()和strncmp()
- strcmp和strncmp
- C strcmp 与 strncmp
- C strcmp 与 strncmp
- strcmp,strncmp函数
- strcmp,strncmp ,memcmp函数
- strncmp源码
- strcmp与strncmp的区别
- 编写类似strcmp() strncmp()函数
- 实现strcmp( )和strncmp( )函数
- 模拟实现strcmp strncmp函数
- strcmp与strncmp的区别
- strcmp与strncmp的区别
- strcmp与strncmp的区别
- 经典vim插件功能说明、安装方法和使用方法介绍(已更新)
- 手工完全恢复(不可转储)
- 关于 AsyncTask 的使用,很好的一篇文章
- 股指期货跨期套利
- Myeclipse10搭建SSH框架自动建立数据表2
- strcmp/strncmp源码分析
- centos oracle
- 整数划分模板
- 几个笔试题(一)
- 删除字符串中的“b”和“ac”
- Asp.net MVC4 使用EF实现数据库的增删改查
- 文本更新和获取
- 加窗的理解。
- Tomcat性能优化及常用命令整理