关于strlen2函数的详细解释

TianLeiShengXue 2011-03-18 03:15:09
关于strlen2函数的详细解释,由于时间匆忙,肯定有笔误之处,将就着看吧!原文在如下链接中:
http://blog.csdn.net/maozefa/archive/2011/03/10/6238782.aspx

size_t strlen2(const char *str)
{
//unsigned即unsigned int,说明了v变量的类型。
unsigned v;

//为了不破坏作为传入参数的原字符串开始地址,于是要声明p这个局部变量,
//以便在字符串中移动,判断其指向的4个字节中是否令有结束字节(\0),
//或判断其指向的一个字节是否是\0。
const char *p = str;

//*p就是取出一个字节的内容,以便在&&运算中判断是否为真;(unsigned)p即把
//指针p转换为无符号数看待,这时p&3是在判断p是否能整除4,因为能整4的整数,其
//最低2位二进制位必为00,而3的二进制表示为“11(其它高位全是0)”,如果p最
//低两位二进制位不是00,那么((unsigned)p & 3)肯定为逻辑真;否则为假。
//整个循环的意思是:如果p指向的字节内容为真、并且地址p不能被4整除的话,那么
//就把p指针逐个字节地向字符串后面移动;否则就退出循环。
while(*p && ((unsigned)p & 3))
p ++;

//判断上面的循环是不是因为p指向的字节内容为\0才退出的,如果是这样,此时p指
//向\0,p - str就是字符串长度,那么函数就可以计算字符串的长度并返回了。
if (*p == 0)
return (size_t)(p - str);

//如果上面的while循环退出是因为p指向的地址能被4整了,也就是p指到了4字节对齐
//的地址上了,我们就可以对p指向的内容以4字节为单位进行判断操作了,这样就比
//逐个字节进行判断操作提高了运行效率。
for (v = 0; !v; p += 4)
{
// *(unsigned*)p表示从p指向的地方出4字节的内容,减去0x01010101的目的是
//为了让4字节中包含\0的字节减去0x01后,该字节变为0xFF(即二进制11111111,
//十进制255),
//再位与上0x80808080就是取4字节中每个字节的最高位(即从0算起的位7),
//只有该字节在减去0x01后大于127,在位与上0x80后,结果该字节的最高位是1、
//其余位是0,否则该字节全是0。
//此句的意思是:p指向的4个字节里,单个字节的内容如果为0或大于128,那么该
//字节进行此句的操作后,最高位为1、其余位为0,并存入v变量中。此句的本意是
//判断4字节中是否含有\0,但却意外地包含了内容大于128的字节情况,所以要进行
//进一步的判断,也就有了下面的if语句。
v = (*(unsigned*)p - 0x01010101) & 0x80808080;

//如果p指向的4字节中,某字节的内容大于128或者为\0,那么v就为真,这是上面那
//句运行的结果。
if (v)
//取出p指向的4字节,并每位取反,其实真正的目的只是取反最高位,如果原字
//节大于128,其最高位取反后为0;原字节为\0,其最高位取反后为1,此时v中
//每字节只有最高位是1的字节才是有效信息,其低7位全是0,此句的&操作后,
//如果是因为p指向的4字节中含有\0,那么结v为是非0的,即真状态,for循环退出;
//如果4个字节全是因为大于128才进入此if判断的,那么v的结果就是0,即假状态,
//整个for循环将继续执行;
v &= ~*(unsigned*)p;
}

//经过上面的处理,只有p-4指向4字节中内容为\0的字节,其在v变量中被翻译成10000000的
//二进制形式,v变量的其余字节全为0x00。(v & 0xff) == 0是判断v变量的最低字节是否
//不为0x00(其实是判断是否是10000000的二进制),如果不是0x00,那就说明找到了\0字节,
//for循环退出;否则v右移8位二进制位后继续判断,p也继续向字符串后面(其实已经指出
//字符串尾之外)移动,是为了在后面的反回语句处计算字符串的长度用。本for语句最多循
//环4次,也就是4字节中,\0在最后一个字节的情况。
for (; (v & 0xff) == 0; p ++)
v >>= 8;

//在反回值中计算字符串的长度,(p - str - 4)中有减去4的操作,是因为在第一个for循环中,
//在找到了包含\0的4个字节后,p继续加了4,所以要在此减去4。其实作者应该在第一个for循环
//退出后就执行p - 4的操作,这样算法会清晰一点点。
return (size_t)(p - str - 4);
}
...全文
358 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
lqfcu2 2012-11-05
  • 打赏
  • 举报
回复
引用 5 楼 xwhmm 的回复:
这个解释太犀利了,强化了我对底层代码实现的了解欲望。。。。。。
strlen2 就是c++builder 2007的strlen汇编函数对应改写的C版本~~
xwhmm 2012-10-29
  • 打赏
  • 举报
回复
这个解释太犀利了,强化了我对底层代码实现的了解欲望。。。。。。
TianLeiShengXue 2012-02-07
  • 打赏
  • 举报
回复
晕~~~偶只是了解点汇编语言罢了!现在已经不在IT业里混了,编程只是业余爱好~~~
Soga 2012-02-07
  • 打赏
  • 举报
回复
楼主能讲一下,是通过怎么样的学习才能达到你这样的高度
xali 2011-03-18
  • 打赏
  • 举报
回复
能猜出来strlen2是以4个字节为单位检查的,所以速度快。
写得很好,没太仔细看,没有发现问题。
一曲肝肠断 2011-03-18
  • 打赏
  • 举报
回复
看着代码变繁了,但是好像能运算的快些的样子似的,帮顶!

69,379

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧