strlen 原型size_t strlen(const char *str);
返回字符串長度(不含結束符 \0),類型為 size_t(無號整數)。
size_t my_strlen(const char *str) {
if (!str) return 0; // 空指針防護
const char *p = str;
while (*p) p++; // 指針後移直到指向 \0
return p - str; // 指針相減得元素個數
}
size_t my_strlen_idx(const char *str) {
if (!str) return 0;
size_t len = 0;
while (str[len]) len++;
return len;
}
int mylen(char *str) {
if (str == NULL) return 0;
int len = 0;
for (; *str++ != '\0';) len++;
return len;
}
優點:簡潔、正確處理空指針、指針自增遍歷。
缺點:返回類型用 int 而非 size_t,長字符串(>2GB)會溢位;參數未加 const,無法傳入字面量常量。
#include <stddef.h> // for size_t
size_t my_strlen(const char *str) {
if (!str) return 0;
const char *end = str;
while (*end) ++end;
return end - str;
}
現代庫實現(如 glibc)使用 SIMD 或字長掩碼一次檢測 4/8/16 字節:
// 簡化版:每次檢測 4 字節(假設 32 位系統)
size_t fast_strlen(const char *s) {
const unsigned int *p = (const unsigned int*)s;
while (!(*p & 0x80808080) && !(*p & 0x40404040) &&
!(*p & 0x20202020) && !(*p & 0x10101010)) p++;
// 找到包含 \0 的字,逐字節精確定位
s = (const char*)p;
while (*s) s++;
return s - (const char*)p + (p - (const unsigned int*)s); // 略
}
實際生產環境直接使用編譯器內建 __builtin_strlen 或庫函數。
strlen("") 返回 0,sizeof("") 返回 1(含 \0)。char *p = "abc"; sizeof(p) 返回指針大小(4/8),非字符串長度。strlen 越界讀取,引發緩衝區溢出漏洞。