深入理解標準庫函數內部邏輯,不僅能應對面試,更能在嵌入式、裸機等無標準庫環境下自給自足。本文從零實現四大核心字串函數,附帶邊界檢查與測試用例。
my_strlen —— 計算字串長度int my_strlen(const char *pStr) {
assert(pStr != NULL);
int len = 0;
while (*pStr++ != '\0') len++;
return len;
}
const char* 保護原字串不被修改。\0 停止。my_strcpy —— 字串拷貝char *my_strcpy(char *strDest, const char *strSrc) {
assert(strDest != NULL && strSrc != NULL);
char *pDest = strDest;
const char *pSrc = strSrc;
while (*pSrc != '\0') {
*pDest++ = *pSrc++;
}
*pDest = '\0'; // 標準 strcpy 會拷貝結束符
return strDest; // 返回目的地址,鏈式調用
}
strDest 以便返回。my_strcpy(c1, c3) 會崩潰)。my_strcmp —— 字串比較int my_strcmp(const char *strDest, const char *strSrc) {
assert(strDest != NULL && strSrc != NULL);
const char *pDest = strDest, *pSrc = strSrc;
int result = 0;
while (*pDest != '\0' || *pSrc != '\0') {
if ((result = *pDest - *pSrc) != 0) break;
pDest++; pSrc++;
}
if (result > 0) return 1;
if (result < 0) return -1;
return 0;
}
>0(正)、=0(等)、<0(負),標準庫僅保證符號,不保證具體值,此處歸一化為 1/0/-1。my_strcat —— 字串連接char *my_strcat(char *strDest, char *strSrc) {
assert(strDest != NULL && strSrc != NULL);
char *pDest = strDest, *pSrc = strSrc;
while (*pDest != '\0') pDest++; // 定位到結束符
while (*pSrc != '\0') *pDest++ = *pSrc++;
*pDest = '\0';
return strDest;
}
strDest 末尾,再追加 strSrc。void Test() {
char c1[5] = "abcd";
char c2[4] = "123";
char c3[20] = "123456";
printf("c1-length: %d\n", my_strlen(c1));
printf("my_strcpy(c1,c2): %s\n", my_strcpy(c1, c2));
// printf("%s\n", my_strcpy(c1, c3)); // 緩衝區溢出,會崩潰!!
printf("my_strcmp(c1,c2): %d\n", my_strcmp(c1, c2));
printf("my_strcmp(c2,c3): %d\n", my_strcmp(c2, c3));
printf("my_strcat(c3,c2): %s\n", my_strcat(c3, c2));
}
assert(ptr != NULL) 捕獲空指針錯誤。pDest = strDest),用於返回或後續計算。strcpy/strcat 必須顯式寫入 \0。strncpy、strncat 提供長度限制版本)。const,目的字串非 const。