首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C語言手寫strlen實現:指針算術、空指針防護與編譯器優化視角

     編輯:關於C

標準實現

size_t my_strlen(const char *str) {
    if (!str) return 0;           // 防護空指針
    const char *p = str;
    while (*p) ++p;               // 指針推進尋找\0
    return p - str;               // 指針相減得長度
}

變體實現對比

版本代碼特點
數組下標size_t i=0; while(str[i])++i; return i;直觀,隱含乘法(按sizeof計算)
指針遞增while(*str++); return str - p - 1;經典教科書寫法,副作用修改參數
for循環緊湊const char *s; for(s=str; *s; ++s); return s-str;無副作用,現代風格推薦
標準庫實現GCC glibc 使用SIMD向量化,按字塊(64B)掃描\0極速,針對對齊/非對齊分支

關鍵細節深度解析

1. 返回類型 size_t

  • 無符號類型,匹配內存地址空間(32位4GB,64位16EB)
  • 避免負長度邏輯錯誤
  • 格式化輸出用%zu (C99)

2. 參數 const char *

  • 承諾不修改內容,允許傳入字符串字面量
  • 內部用const char *遍歷,保持const正確性

3. 空指針處理策略

// 策略A:返回0(防崩潰,掩蓋bug)
if (!str) return 0;

// 策略B:斷言失敗(暴露bug,調試階段推薦)
assert(str != NULL);

// 策略C:未定義行為(標準庫行為,最高性能)
// 直接 dereference NULL → SIGSEGV

4. 編譯器優化視角

// 編譯器可能優化為:
size_t my_strlen(const char *str) {
    return __builtin_strlen(str); // 內聯SIMD指令序列
}
  • 常量字符串長度編譯期計算:strlen("hello") → 常數5
  • 循環不變量外提、向量化、循環展開
  • 鏈接時優化(LTO)可消除函數調用開銷

測試用例

int main() {
    const char *tests[] = {
        "", "a", "hello", "中文測試", NULL
    };
    for (int i = 0; tests[i]; ++i) {
        printf("'%s' -> len=%zu, std=%zu\n",
               tests[i], my_strlen(tests[i]), strlen(tests[i]));
    }
    // 空指針測試(策略A)
    printf("NULL -> %zu\n", my_strlen(NULL));
    return 0;
}

面試延伸問題

  1. 不使用庫函數實現strcpy/strcmp/strchr —— 同樣指針算術核心
  2. 計算UTF-8字符串字符數(非字節數) —— 需解碼多字節序列
  3. 檢測字符串是否為合法UTF-8 —— 狀態機校驗字節模式
  4. 線程安全的strlen —— 純讀操作天然線程安全,無共享寫入
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved