|
|
发表于 2006-11-17 15:59:00
|
显示全部楼层
Re:程序面试试题(节选)
/* 这个strlen采用4字节一步的方法遍历字符串(因为现代机器上32位操作最快),每一步都判断有没有0字节 */
size_t strlen (const char *str)
{
const char *char_ptr;
const unsigned long int *longword_ptr;
unsigned long int longword, himagic, lomagic;
/* 下面这一块是先把指针走到地址是4的倍数的地方,再开始遍历。'& (sizeof (longword) - 1)) '相当于char_ptr % 4 */
for (char_ptr = str; ((unsigned long int) char_ptr
& (sizeof (longword) - 1)) != 0;
++char_ptr)
if (*char_ptr == '\0')
return char_ptr - str;
/* 这里用一个long指针接管char指针 */
longword_ptr = (unsigned long int *) char_ptr;
himagic = 0x80808080L;
lomagic = 0x01010101L;
for (;;)
{
longword = *longword_ptr++;
/* 下面这个方法很厉害,用来检测当前4字节中有无0字节。下面再说 */
if (((longword - lomagic) & himagic) != 0)
{
const char *cp = (const char *) (longword_ptr - 1);
if (cp[0] == 0)
return cp - str;
if (cp[1] == 0)
return cp - str + 1;
if (cp[2] == 0)
return cp - str + 2;
if (cp[3] == 0)
return cp - str + 3;
}
}
}
(longword - lomagic) & himagic =
longword
- 00000001 00000001 00000001 00000001
& 10000000 10000000 10000000 10000000
这算是一种并行方法吧,把4个字节同时算。那只要看一个字节就行了。
就是说把1~127的字节都抹成0,而把0变成非0... |
|