青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

統計

  • 隨筆 - 50
  • 文章 - 42
  • 評論 - 147
  • 引用 - 0

留言簿(6)

隨筆分類

文章分類

Link

搜索

  •  

積分與排名

  • 積分 - 167517
  • 排名 - 159

最新評論

閱讀排行榜

評論排行榜

從小函數實現看應聘者的編程素質(atoi.strcmp...)

在程序員面試的時候,面試官通常會讓你實現一個或幾個C語言里的庫函數,以此來檢查你的編程功底。類似的函數實現有atoi.itoa.atof.strcmp.strcpy.memset.memcpy等等。

在平時的編程中,我們可能極少有機會要自己實現這些函數。但是面試官卻很喜歡用這些東西考察你。實際上所謂的"考察",永遠是個偽命題。面試者其實不是用這個小函數的實現來考察"你行",而大部分寄希望于用這個小函數來"你不行"。隨便在網上搜搜,就會發現很多討論這個的帖子,其中大部分都有一些解答(用來證明你不行的理由),仔細琢磨就會發現其中的有一些還蠻有道理,但有一些解釋實在是有點牽強。

說實話,這些函數實現的考察,作用還是有的,但是就我自己感覺,作用還不在單純的編程能力上,在本文的最后,我會發表我自己的一點看法。還是先說說這些函數的一些實現,都是我自己比較認可的版本,肯定也不一定完全符合面試官的要求,但無論如何,如果我碰到面試官這樣考我,我肯定拿下面的答案應付了:)。

首先來看看xtox系列的函數,這類函數涉及數類型和字符類型之間的轉換,考察的一個知識點是如何將一個數字轉化為對應的字符或者如何將對應的字符轉化為數字(以下的代碼演示了這些轉換方法),在我知道這個方法以前,我都是寫個函數,建立字符和數字的對應查詢關系(相當于建立了一個數字和字符的查詢快表)來匹配兩者的對應關系。代碼應該來說比較簡單,就不加注釋了,后文會提到需要額外說明的幾點。(特別說明:為篇幅計,下面的代碼出現了兩行代碼出現在一行的情況,真實的代碼中可能不希望這樣)

-------------------------------------------------------atoi----------------------------------------------------------

int atoi(const char* str)
{
    int sign = 0,num = 0;
    assert(NULL != str);
    while (*str == ' ')
    {
        str++;
    }
    if ('-' == *str)
    {
        sign = 1; str++;
    }
    while ((*str >= '0') && (*str <= '9'))
    {
        num = num*10 + (*str - '0'); //就是這一行,將對應字符轉化為數字

        str++;
    }
    if(sign == 1)
        return -num;
    else
        return num;
}

-------------------------------------------------atof------------------------------------------------------------

double atof(const char* str)
{
    double val = 0.0,power = 0.0;
    int sign = 0;
    assert(NULL != str);
    while (*str == ' ')
    {
        str++;
    }
    sign = (*str == '-')? -1 : 1;
    if ('-' == *str || '+' == *str)
    {
        str++;
    }
    while ((*str >= '0')&&(*str <= '9'))
    {
        val = val* 10.0 + (*str - '0'); str++;
    }
    if ('.' == *str)
    {
        str++;
    }
    power = 1.0;
    while ((*str >= '0')&&(*str <= '9'))
    {
        val = val* 10.0 + (*str - '0');
        power *= 10; str++;
    }
    return sign*val/power;
}

---------------------------------------------itoa------------------------------------------------------------------------

char* itoa(int val,char* buf,unsigned int radix)
{
    char *bufptr;
    char *firstdig;
    char temp;
    unsigned int digval;
    assert(buf != NULL);
    bufptr = buf;
    if (val < 0)
    {
        *bufptr++ = '-'; val = (unsigned int)(-(int)val);
    }
    firstdig = bufptr;
    do
    {
        digval =(unsigned int) val % radix;    val /= radix;
        if (digval > 9)
        {
            *bufptr++ = (char)(digval - 10 + 'a');
        }
        else
        {
            *bufptr++ = (char)(digval + '0');
        }
    } while(val > 0);
    *bufptr-- = '\0';//設置字符串末尾,并將指針指向最后一個字符
    do //反轉字符
    {
        temp = *bufptr;     *bufptr = *firstdig;  *firstdig = temp;
        --bufptr; ++firstdig;
    } while(firstdig < bufptr);
    return buf;
}

----------------------------------------------itoa.end-------------------------------------------------------------------

下面是strxxx和memxxx系列,下面的一些實現,有些我到現在還抱有一些疑問,比如說strcmp函數,為什么要強制轉換成unisigned以及為什么要用*dst來判斷循環終止而不用*src,還沒有找到更好的答案或者徹底弄清楚這些問題,以后弄清楚了再補上。

-------------------------------------------------------strcmp------------------------------------------------------------

int strcmp(const char* src,const char* dst)
{
    int ret = 0;
    if (src == dst)
    {
        return 0;
    }
    assert(NULL != src);//期待源字符串不為空
    if (dst == NULL)
    {
        return -1;
    }
    while (!(ret = *(unsigned char*)src - *(unsigned char*)dst)&& *dst)
    {
        ++src,++dst;
    }
    if (ret < 0)
    {
        ret = -1;
    }
    else if (ret > 0)
    {
        ret = 1;
    }
    return ret;
}

-------------------------------------------strcpy------------------------------------------------------------------------

char* strcpy(char* dst,const char* src)
{
    char* strDst = dst;
    assert(src != NULL && dst != NULL);//拷貝空串被認為是沒有意義的,使用assert檢查
    while ((*dst++ = *src++) != '\0')
    {
        NULL;
    }
    return strDst;
}

--------------------------------------memcpy-------------------------------------------------------------------------

void* memcpy(void* dst,const void* src,size_t count)
{
    char* pbTo = (char*)dst;
    char* pbFrom = (char*)src;
    assert(dst!= NULL && src != NULL);
    assert(pbTo >= pbFrom+count || pbFrom >= pbTo + count);//防止內存重疊(overlap)
    while (count-- > 0)
    {
        *pbTo++ = *pbFrom++;
    }
    return dst;
}

--------------------------------------memmove---------------------------------------------------------------------

void* memmove(void* dst,const void* src,size_t count)
{
    char* pbTo = (char*)dst;
    char* pbFrom = (char*)src;
    assert(dst != NULL && src != NULL);
    if (dst <= src || pbTo >= pbFrom + count)//沒有overlap的情況,直接拷貝
    {
        while (count-- > 0)
        {
            *pbTo++ = *pbFrom++;
        }
    }
    else
    {
        pbTo = pbTo + count -1;//overlap的情況,從高位地址向低位拷貝
        pbFrom = pbFrom + count -1;
        while (count-- > 0)
        {
            *pbTo-- = *pbFrom--;
        }
    }
    return dst;
}

--------------------------------------memset-------------------------------------------------------------------------

void* memset(void* buf,int c,size_t count)
{
    char* pvTo = (char*)buf;
    assert(buf != NULL);
    while (count-- >0)
    {
        *pvTo++ = (char)c;
    }
    return buf;
}

--------------------------------------memset.end---------------------------------------------------------------------

這些函數的代碼都很短小,但是面試官對你這幾行短小的代碼抱有很高的期望。

首先,正確性!實現得都不正確,那還搞毛啊,其他的小問題肯定談都不用談了,直接out!正確性要注意的地方,每個函數的功能起碼要了解(memmove等),邊界的檢查不能出錯;返回值也是要注意的地方。

其次,assert不能少!對指針有效性的檢查是非常必要的,特別是在memcpy中,存在兩個assert,分別檢查指針的有效性以及內存是否交疊。針對第二個assert還要加上必要注釋(因為代碼的維護者并不是一眼就能看出這個assert的涵義,搞不好可能直接在維護代碼中刪掉這么重要的一個assert檢查)。

然后要注意的有:指針的有效性檢驗,最好是與NULL進行比較。最后,空語句(strcpy)、大括號一個都不能少。

我自己的想法,其實這些函數(包含其他小的函數),難度不算太大,當然要寫得完全正確也非常不易。但是,在正確性的基礎上,面試官期望從你的代碼中發現你身上作為程序員的素質和態度!當我們編程的時候,我們的腦海里真的想的是手里敲的代碼嗎?當我們正在實現一個函數或者一個類的時候,我們真的認真考慮了它應該怎樣被實現嗎?針對這些小函數(當然,大函數更一樣了),參數的有效性檢查是always必要的(不要相信任何輸入!),邊界的有效性檢查是很容易出錯的!每一行代碼都要想清楚為什么要這么實現,我想,只要你腦子所想是你手上所要做的,我手"寫"我心,自然是不會出錯了,起碼也應該知道自己錯在哪里,下次改正就好。《微軟C編程精粹》最后一句話話告訴我們:成功地書寫無錯代碼的關鍵可以總結為一個總的原則,即絕不允許同樣的錯誤出現兩次!

最后,推薦一些參考書,就我自己的閱讀經驗來看,這些參考書對如何寫好這些小函數還是很有借鑒意義的,按重要性排序:

1.《編程精粹—微軟編寫優質無錯C程序秘訣》,Writing Clean Code——Microsoft Techniques for Developing Bug-free C Programs;

2.《高質量C\C++編程指南》,一本書,也是林銳編的,網上廣為流傳的同名小冊子算是精簡版;

3.《程序員面試寶典》;

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/winglet/archive/2008/08/26/2831605.aspx

posted on 2009-08-24 15:17 pear_li 閱讀(3179) 評論(0)  編輯 收藏 引用 所屬分類: C++

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲福利视频二区| 亚洲欧美激情精品一区二区| 一区二区三区国产精华| 狠狠色狠狠色综合日日91app| 亚洲国产精品久久久久久女王| 国产精品国产精品国产专区不蜜| 蜜桃视频一区| 久久一区免费| 国产精品免费观看视频| 亚洲一区影院| 久久国内精品视频| 亚洲日产国产精品| 欧美天堂在线观看| 久久天天狠狠| 亚洲国产一区二区三区a毛片 | 久久亚洲春色中文字幕久久久| 99pao成人国产永久免费视频| 欧美资源在线| 欧美中文在线观看国产| 国产精品成av人在线视午夜片| 亚洲第一网站| 在线欧美小视频| 久久www成人_看片免费不卡| 欧美一区二区三区的| 国产精品毛片大码女人| 正在播放亚洲一区| 亚洲欧美成人一区二区三区| 欧美视频中文字幕在线| 中日韩男男gay无套| 亚洲一区观看| 国产精品女人毛片| 亚洲夜间福利| 久久精品国产精品亚洲精品| 国产欧美日韩视频在线观看| 午夜精品一区二区三区电影天堂| 亚洲专区在线| 国产精品人人爽人人做我的可爱| 亚洲视频一区二区| 亚洲一区二区三区在线观看视频| 欧美偷拍一区二区| 亚洲综合日韩在线| 久久久久久久精| 亚洲国产91精品在线观看| 蜜臀av一级做a爰片久久| 亚洲高清不卡一区| 亚洲特级片在线| 国产精品毛片va一区二区三区| 午夜精品福利一区二区三区av | 亚洲一卡久久| 国产精品综合| 久久久久久久久久久一区| 欧美大片专区| 亚洲午夜精品| 韩曰欧美视频免费观看| 麻豆精品一区二区综合av| 亚洲伦理在线免费看| 午夜精品一区二区在线观看| 黑人巨大精品欧美黑白配亚洲 | 麻豆成人精品| 一本大道久久精品懂色aⅴ| 香蕉免费一区二区三区在线观看 | 欧美黄色免费| 亚洲综合色网站| 男同欧美伦乱| 亚洲一区二区在| 一区二区在线观看视频在线观看| 欧美黄色视屏| 西西人体一区二区| 亚洲国产岛国毛片在线| 亚洲欧美激情四射在线日 | 精品成人一区二区三区| 欧美日韩不卡在线| 欧美亚洲免费高清在线观看| 91久久国产自产拍夜夜嗨| 欧美在线视频免费| 亚洲成人在线视频播放| 国产精品久久久久秋霞鲁丝| 免费欧美在线| 久久精品二区亚洲w码| 日韩一级精品| 亚洲国产小视频在线观看| 久久精品一区二区三区四区| 这里只有视频精品| 亚洲人成网站精品片在线观看| 国产精品欧美精品| 欧美日韩成人综合在线一区二区| 欧美专区日韩视频| 亚洲在线观看| 一本久道久久综合中文字幕| 亚洲国产成人tv| 久久香蕉国产线看观看网| 亚洲一二三级电影| 亚洲精品自在久久| 在线观看一区| 激情偷拍久久| 国产中文一区二区三区| 国产乱码精品一区二区三区五月婷 | 亚洲一区二区三| 亚洲美女av在线播放| 亚洲国产精品国自产拍av秋霞| 久久免费偷拍视频| 久久精品人人| 久久成人一区二区| 午夜免费在线观看精品视频| 亚洲综合大片69999| 亚洲网站在线看| 亚洲午夜一区二区| 在线亚洲国产精品网站| 亚洲视频免费看| 正在播放亚洲一区| 亚洲视频网站在线观看| 亚洲一区二区三区在线播放| 亚洲图片你懂的| 亚洲系列中文字幕| 午夜精品久久久久久久白皮肤| 中文国产成人精品| 亚洲女人小视频在线观看| 亚洲免费伊人电影在线观看av| 在线中文字幕一区| 亚洲资源av| 久久精品国产亚洲aⅴ| 久久久久久久高潮| 欧美成人中文| 亚洲精品日韩综合观看成人91| 亚洲老司机av| 亚洲欧美日本视频在线观看| 亚洲欧美日韩一区二区在线| 久久精品国产一区二区电影| 久久蜜桃资源一区二区老牛| 欧美成人嫩草网站| 欧美体内谢she精2性欧美| 国产精品区免费视频| 国产亚洲精品v| 亚洲精品国精品久久99热一| 一区二区三区精品视频在线观看 | 欧美成人亚洲成人| 亚洲九九九在线观看| 亚洲午夜久久久久久久久电影院 | 亚洲男女自偷自拍| 久久精品人人| 欧美精品尤物在线| 国产人成精品一区二区三| 亚洲丁香婷深爱综合| 亚洲深夜福利视频| 久久综合国产精品台湾中文娱乐网| 奶水喷射视频一区| 中文一区在线| 久久久久久成人| 欧美日韩午夜视频在线观看| 国产欧美日韩综合| 亚洲每日在线| 久久精品人人做人人综合| 欧美激情视频一区二区三区不卡| 一本综合精品| 免费成人高清视频| 国产精品视频免费一区| 亚洲国产欧美日韩| 欧美一区国产二区| 亚洲欧洲中文日韩久久av乱码| 午夜免费电影一区在线观看| 欧美11—12娇小xxxx| 国产亚洲精品激情久久| 夜夜嗨av一区二区三区| 久久久噜噜噜| 亚洲视频一起| 欧美日韩八区| 在线精品国产成人综合| 欧美一区二区国产| 一本久道久久综合婷婷鲸鱼| 久久野战av| 国产在线日韩| 午夜精品亚洲| 日韩一区二区福利| 欧美黄色大片网站| 影音先锋日韩精品| 久久精视频免费在线久久完整在线看| 夜夜嗨av色一区二区不卡| 麻豆精品视频在线观看| 极品av少妇一区二区| 久久精品视频va| 亚洲尤物影院| 国产精品分类| 亚洲午夜精品17c| 日韩午夜av在线| 欧美黄色免费| 日韩亚洲欧美中文三级| 亚洲高清不卡在线| 欧美a级片一区| 樱花yy私人影院亚洲| 久久综合九色综合网站| 欧美在线资源| 韩国亚洲精品| 免费黄网站欧美| 久久综合电影一区| 在线观看欧美日本| 欧美大片va欧美在线播放| 蜜臀a∨国产成人精品 | 在线免费观看日本一区| 美腿丝袜亚洲色图| 久久一二三区|