百度面試題:本身實現strlen,考慮32位,64位機器,考慮性能

沒辦法, 如今的大公司面試就面這個, 你不得不研究下底層的實現.面試

要點:
1) 字長邊界對齊以便加快速度. 對齊時也要考慮機器的位數哦.測試

2) 一次測試4個(或者8個)字節中是否含零的技巧.
3) 須要自適應32bit/64bit機器. 
   定義magic變量是要使用long, 而且是unsigned的, 若是是unsigned int就不行, 只能在32位下用.
   判斷字長時要sizeof(long) 而不是sizeof(int).net

如何一次測試4個字節是否含零?
一個關鍵技巧是經過異或操做判斷通過運算後一個數的那些bit位未發生變化.結果爲1的bit位未發生變化.
相似的,&操做能夠判斷那些位發生了變化.
舉例,兩個數a,b, 試比較兩個數有那些bit位是相同的?
a^~b , 結果中bit位爲1的位是相同的.
a&~b , 結果中bit位爲1的位是不一樣的.blog

一片博文講解的很精彩
strlen高效實現 
http://blog.csdn.net/lonelysky/article/details/6614422string

 

#include <stdio.h>
#include <string.h>
 
int my_strlen(const char * str)
{
    const char * pstr = str;
    
    // 先將地址邊界對齊  & 操做更高效, 避免了%取餘運算
    //for (; (unsigned long)pstr%(sizeof(long)) != 0; ++pstr)
    for (; (unsigned long)pstr & (sizeof(long)-1) != 0; ++pstr)
    {
        if (pstr[0] == '\0')
            return pstr - str;
    }
 
    unsigned long himagic = 0x80808080;
    unsigned long lomagic = 0x01010101;
 
    // 若是是64位
    if (sizeof(long) > 4)
    {
        himagic = ((himagic << 16) << 16) | himagic;
        lomagic = ((lomagic << 16) << 16) | lomagic;
    }
 
    unsigned long longword = 0;
    for (;; pstr+=sizeof(long))
    {
        longword = *(unsigned long*)pstr;
 
        // (longword - lomagic) & ~longword 可測試出, 相減以後longword變量的那些bit發生了改變
        // ... & himagic 可測試出, 變化的那些bit位中是否包含各個字節的最高位
        if (((longword - lomagic) & ~longword & himagic) != 0)
        {
            if (pstr[0] == '\0')
                return pstr - str;
            if (pstr[1] == '\0')
                return pstr - str + 1;
            if (pstr[2] == '\0')
                return pstr - str + 2;
            if (pstr[3] == '\0')
                return pstr - str + 3;
            if (sizeof(long) > 4)
            {
                if (pstr[4] == '\0')
                    return pstr - str + 4;
                if (pstr[5] == '\0')
                    return pstr - str + 5;
                if (pstr[6] == '\0')
                    return pstr - str + 6;
                if (pstr[7] == '\0')
                    return pstr - str + 7;
            }
        }
    }
 
    // never come to here...
    return 0;
}
int main()
{
    char * str = "helloworldaaaaa";
    int ret = 0;
 
    ret = my_strlen(str+1);
    printf("len : %d\n", ret);
 
    ret = strlen(str+1);
    printf("len : %d\n", ret);
 
    return 0;
    
}it

輸出以下:
:!g++ -Wall -g strlen.cpp -o strlen && ./strlen
len : 14
len : 14
--------------------- 
做者:zdl1016 
來源:CSDN 
原文:https://blog.csdn.net/zdl1016/article/details/8683418 
版權聲明:本文爲博主原創文章,轉載請附上博文連接!io

相關文章
相關標籤/搜索