strlen.c

/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Written by Torbjorn Granlund (tege@sics.se),
   with help from Dan Sahlin (dan@sics.se);
   commentary by Jim Blandy (jimb@ai.mit.edu).

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#include <string.h>
#include <stdlib.h>

#undef strlen

#ifndef STRLEN
# define STRLEN strlen
#endif

/* Return the length of the null-terminated string STR.  Scan for
   the null terminator quickly by testing four bytes at a time.  */
size_t
STRLEN (const char *str)
{
  const char *char_ptr;
  const unsigned long int *longword_ptr;
  unsigned long int longword, himagic, lomagic;

  /* Handle the first few characters by reading one character at a time.
     Do this until CHAR_PTR is aligned on a longword boundary.  */
  for (char_ptr = str; ((unsigned long int) char_ptr
            & (sizeof (longword) - 1)) != 0;
       ++char_ptr)
    if (*char_ptr == '\0')
      return char_ptr - str;

  /* All these elucidatory comments refer to 4-byte longwords,
     but the theory applies equally well to 8-byte longwords.  */

  longword_ptr = (unsigned long int *) char_ptr;

  /* Bits 31, 24, 16, and 8 of this number are zero.  Call these bits
     the "holes."  Note that there is a hole just to the left of
     each byte, with an extra at the end:

     bits:  01111110 11111110 11111110 11111111
     bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD

     The 1-bits make sure that carries propagate to the next 0-bit.
     The 0-bits provide holes for carries to fall into.  */
  himagic = 0x80808080L;
  lomagic = 0x01010101L;
  if (sizeof (longword) > 4)
    {
      /* 64-bit version of the magic.  */
      /* Do the shift in two steps to avoid a warning if long has 32 bits.  */
      himagic = ((himagic << 16) << 16) | himagic;
      lomagic = ((lomagic << 16) << 16) | lomagic;
    }
  if (sizeof (longword) > 8)
    abort ();

  /* Instead of the traditional loop which tests each character,
     we will test a longword at a time.  The tricky part is testing
     if *any of the four* bytes in the longword in question are zero.  */
  for (;;)
    {
      longword = *longword_ptr++;

      if (((longword - lomagic) & ~longword & himagic) != 0)
    {
      /* Which of the bytes was the zero?  If none of them were, it was
         a misfire; continue the search.  */

      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;
      if (sizeof (longword) > 4)
        {
          if (cp[4] == 0)
        return cp - str + 4;
          if (cp[5] == 0)
        return cp - str + 5;
          if (cp[6] == 0)
        return cp - str + 6;
          if (cp[7] == 0)
        return cp - str + 7;
        }
    }
    }
}
libc_hidden_builtin_def (strlen)

上面是glibc-2.25的strlen函數(shù)的的源代碼,我這里呢精簡一下,因為我用的平臺是64位的砖织,所以我就省略了32位的一些判斷,順便加了一些注釋末荐,方便理解

unsigned long long strlen (const char *str){
    for (const char *char_ptr = str; (unsigned long long) char_ptr & 7; ++char_ptr)
        if (*char_ptr == 0)
            return char_ptr - str;
    /*
    這里可能有人不懂侧纯,char_ptr & 7這是在做什么
    解釋一下,這里考慮的一個對齊的甲脏,這個循環(huán)最多只能執(zhí)行7次
    分別是001眶熬,010妹笆,011,100娜氏,101拳缠,110,111贸弥,
    即char_tr的低三位為如上值時
    */
    for (const unsigned long long *longword_ptr = (unsigned long long*) str;;++longword_ptr){
        unsigned long long longword = *longword_ptr;
        if ((longword - 0X0101010101010101) & ~longword & 0X8080808080808080){
            for (unsigned long long i = 0; i < 8; ++i) {
                const char *cp = (const char *)longword_ptr;
                if(cp[i] == 0)
                    return cp - str + i;
            }
            /*
            上面也有一個難點:就是那個條件
            上面的是64位的8字的窟坐,我用8字的char 講一下
            char c;
            ~c & 0X80
            這個的結果只有兩種
            一種是0X80,當且僅當~C的最高為1時就是C的最高位為0時成立
            一種是0
            (c-1)& 0X80的結果也只有兩種
            一種是0X80茂腥,當且僅當(c-1)的最高為1時成立
            一種是0
            要使結果是非0狸涌,即0X80,只要同時滿足兩種條件
            (c-1)& 0X80 & (~c & 0X80)最岗!= 0 即(c-1)& ~c & 0X80同時成立
            即c的最高位是0帕胆,而且(c-1)的最高位是1,當且僅當c等于0時成立
            */
        }
    }
}

有人喜歡的話般渡,給點個贊

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末懒豹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子驯用,更是在濱河造成了極大的恐慌脸秽,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蝴乔,死亡現(xiàn)場離奇詭異记餐,居然都是意外死亡,警方通過查閱死者的電腦和手機薇正,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門片酝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人挖腰,你說我怎么就攤上這事雕沿。” “怎么了猴仑?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵审轮,是天一觀的道長。 經(jīng)常有香客問我辽俗,道長疾渣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任崖飘,我火速辦了婚禮稳衬,結果婚禮上,老公的妹妹穿的比我還像新娘坐漏。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布粒氧。 她就那樣靜靜地躺著歧杏,像睡著了一般祸轮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上板丽,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機與錄音趁尼,去河邊找鬼埃碱。 笑死,一個胖子當著我的面吹牛酥泞,可吹牛的內容都是我干的砚殿。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼芝囤,長吁一口氣:“原來是場噩夢啊……” “哼似炎!你這毒婦竟也來了?” 一聲冷哼從身側響起悯姊,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤羡藐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后悯许,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體仆嗦,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年先壕,在試婚紗的時候發(fā)現(xiàn)自己被綠了瘩扼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡启上,死狀恐怖邢隧,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情冈在,我是刑警寧澤倒慧,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站包券,受9級特大地震影響纫谅,放射性物質發(fā)生泄漏。R本人自食惡果不足惜溅固,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一付秕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧侍郭,春花似錦询吴、人聲如沸掠河。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽唠摹。三九已至,卻和暖如春奉瘤,著一層夾襖步出監(jiān)牢的瞬間勾拉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工盗温, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留藕赞,地道東北人。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓卖局,卻偏偏與公主長得像斧蜕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子吼驶,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內容