標準庫<string.h>提供的strlen、strcpy、strcmp是C語言開發中最高頻的字串操作。深入理解其底層實現邏輯,不僅能應對面試考察,更能在嵌入式、底層開發等無標準庫環境下靈活應變。本文提供三種不同風格的手工實現,並解析指標與陣列操作的本質差異。
strlen核心邏輯:從首字元遍歷,遇到空字元'\0'停止,計數器即為有效長度。
int mystrlen1(char s[]) {
int len = 0;
while (s[len] != '\0') {
len++;
}
return len;
}
int mystrlen2(char *s) {
int len = 0;
while (*s != '\0') {
len++;
s++; // 指標後移
}
return len;
}
測試主程式:
int main() {
char str[] = "hello";
printf("版本一長度: %d\n", mystrlen1(str)); // 輸出 5
printf("版本二長度: %d\n", mystrlen2(str)); // 輸出 5
return 0;
}
strcpy核心邏輯:將源字串src逐字元複製到目標字串dest,包含結束符'\0'。前提:dest必須有足夠空間。
void mystrcpy1(char dest[], char src[]) {
int i = 0;
while ((dest[i] = src[i]) != '\0') { // 賦值與判斷合一
i++;
}
}
void mystrcpy2(char *dest, char *src) {
while ((*dest = *src) != '\0') {
dest++;
src++;
}
}
void mystrcpy3(char *dest, char *src) {
while (*dest++ = *src++); // 單分號結束,極度精簡
}
解析: *dest++ = *src++ 先解引用賦值,再將兩指標後移。表達式值為賦值後的字元,遇到'\0'(值為0,假)迴圈結束。
strcmp核心邏輯:逐字元比較兩字串,首個不同字元的ASCII碼差值即為返回值。相等返回0,s1 > s2返回正數,反之負數。
int mystrcmp1(char s1[], char s2[]) {
int i = 0;
for (; s1[i] == s2[i]; i++) {
if (s1[i] == '\0') return 0; // 同時到達結尾,相等
}
return s1[i] - s2[i]; // 返回差值
}
int mystrcmp2(char *s1, char *s2) {
while (*s1 == *s2) {
if (*s1 == '\0') return 0;
s1++;
s2++;
}
return *s1 - *s2;
}
| 維度 | 陣列下標法 | 指標法 |
|---|---|---|
| 可讀性 | 高,適合初學者 | 中,需理解指標運算 |
| 效能 | 編譯器優化後幾乎一致 | 底層實際機器指令更貼近 |
| 參數形式 | char s[] 實為 char *s | 直接使用 char *s |
| 常見錯誤 | 越界訪問、忘記處理'\0' | 指標未復位導致後續邏輯錯誤、修改字串常量崩潰 |
char *p = "hello"; p[0] = 'H'; 會導致段錯誤(常量區唯讀)。複製時需確保目標空間可寫(如char dest[100])。strncpy或strlcpy防止緩衝區溢出。strcmp返回差值而非單純-1/0/1,利用差值可實現字典序排序。手工實現標準庫函數,是深入C語言「指標與記憶體」本質的最佳路徑。建議讀者對照標準庫源碼(如glibc、musl libc),體會生產級代碼對邊界條件、對齊優化、向量化指令的極致處理。