節選自 Linux Kernel lib/string.c(Linus Torvalds 早期版本),展示最基礎、可移植的 C 實作,無平台相關優化指令。
// strcpy:簡潔的指標遞增複製
char *strcpy(char *dest, const char *src) {
char *tmp = dest;
while ((*dest++ = *src++) != '\0') ;
return tmp;
}
// strcmp:利用 signed char 相減直接得到比較結果
int strcmp(const char *cs, const char *ct) {
register signed char __res;
while (1) {
if ((__res = *cs - *ct++) != 0 || !*cs++) break;
}
return __res;
}
// memcpy:逐位元組複製,不處理重疊
void *memcpy(void *dest, const void *src, size_t count) {
char *tmp = dest, *s = (char *)src;
while (count--) *tmp++ = *s++;
return dest;
}
// memmove:正確處理重疊,分前後向複製
void *memmove(void *dest, const void *src, size_t count) {
char *tmp, *s;
if (dest <= src) { tmp = dest; s = (char *)src; while (count--) *tmp++ = *s++; }
else { tmp = (char *)dest + count; s = (char *)src + count; while (count--) *--tmp = *--s; }
return dest;
}
// memset:逐位元組填充
void *memset(void *s, char c, size_t count) {
char *xs = s;
while (count--) *xs++ = c;
return s;
}
register 關鍵字建議編譯器使用暫存器(現代編譯器會自動優化)。tmp),符合標準庫慣例,支援鏈式呼叫。strtok 使用靜態變數 ___strtok 保存狀態,故非執行緒安全。strchr, strpbrk, strstr)採用雙層迴圈,時間複雜度 O(n*m),未使用 KMP/BM 等進階演算法。現代 glibc/musl 針對特定架構(x86_64, ARM64)提供 SIMD(SSE2, NEON)向量化版本,並針對小型字串使用展開迴圈、預取指令等技巧,效能遠超此參考實作。
閱讀核心庫原始碼有助於理解標準庫語義邊界、指標運算技巧、以及為何某些函數(如 strncpy)有特定行為設計。