在C語言中,計算字符串長度是基礎操作之一。雖然標準庫提供了 strlen 函數,但理解其底層實現有助於掌握指針運算、遞歸思維及數組遍歷的核心邏輯。本文將詳細講解三種常見的實現方式:計數器法、指針差值法與遞歸法,並附帶完整代碼示例。
此方法利用一個計數器變量,通過 while 循環逐個檢查字符,直到遇到空字符 '\0' 為止。每移動一位指針,計數器加一,最終返回計數值。
#include <stdio.h>
#include <assert.h>
int my_strlen(char *str) {
int count = 0;
assert(str != NULL); // 防御性編程:確保指針有效
while (*str != '\0') {
count++;
str++;
}
return count;
}
int main(void) {
char *arr = "abcef";
int ret = my_strlen(arr);
printf("%d\n", ret); // 輸出 5
return 0;
}
優點:邏輯清晰,易於理解,適合初學者。
缺點:需要額外的計數器變量,指針移動會改變原指針值(若需保留原指針應使用臨時變量)。
此方法記錄字符串起始地址,然後移動一個臨時指針直到字符串結尾,最後用結尾指針減去起始指針,再減 1(因為指針指向 '\0' 的下一位),即可得到長度。
#include <stdio.h>
#include <assert.h>
int my_strlen(const char *str) {
assert(str != NULL);
const char *start = str;
while (*str != '\0') {
str++;
}
return (int)(str - start); // 指針相減得到元素個數
}
int main(void) {
char *arr = "abcdef";
printf("%d\n", my_strlen(arr)); // 輸出 6
return 0;
}
優點:無需額外計數器,代碼簡潔,體現指針運算的威力。
注意:參數應用 const char* 表明不修改字符串內容,指針相減結果為 ptrdiff_t 類型,轉換為 int 需注意長字符串可能溢出。
遞歸將問題分解為「首字符長度 1 + 剩餘字符串長度」。基線條件為遇到 '\0' 返回 0,否則指針後移並遞歸調用。
#include <stdio.h>
#include <assert.h>
int my_strlen(const char *str) {
assert(str != NULL);
if (*str == '\0') {
return 0;
}
return 1 + my_strlen(str + 1);
}
int main(void) {
char *arr = "abcdef";
printf("%d\n", my_strlen(arr)); // 輸出 6
return 0;
}
優點:代碼極簡,展示遞歸思想。
缺點:函數調用開銷大,極長字符串可能導致棧溢出,生產環境不推薦。
strlen,它經過優化(如按字節塊讀取、SIMD 指令)。