首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言標準庫函數模擬實現:strcpy、strstr、strcat 核心源碼解析

     編輯:關於C語言

C語言標準庫函數模擬實現:strcpy、strstr、strcat 核心源碼解析

手寫標準庫字串函數是 C 語言指標功力的試金石。本文提供 **生產級實現**,涵蓋參數驗證、const 正確性、返回值設計、重疊處理、效能優化,並對比原始碼的常見缺陷。

1. strcpy —— 字串複製

#include <assert.h>
#include <string.h>

char *my_strcpy(char *dest, const char *src) {
    assert(dest != NULL && src != NULL);  // 參數驗證
    
    char *ret = dest;  // 保存起始位址,支援鏈式調用
    
    // 核心複製迴圈:包含結束符 \0
    while ((*dest++ = *src++) != '\0') 
        ;  // 空語句
    
    return ret;
}

關鍵設計點

  • const 正確性:`src` 不修改,標記 `const`
  • 返回 dest 起始位址:支援 `strcat(strcpy(buf, "hello"), "world")` 鏈式調用
  • 複製包含 `\0`:迴圈條件賦值後判斷,確保結束符被複製
  • 不處理重疊:行為未定義,呼叫者責任保證不重疊 (同標準庫)

2. strstr —— 子串查找 (朴素演算法)

char *my_strstr(const char *haystack, const char *needle) {
    assert(haystack && needle);
    
    if (*needle == '\0') return (char *)haystack;  // 空 needle 返回 haystack
    
    for (const char *h = haystack; *h; h++) {
        const char *p1 = h;
        const char *p2 = needle;
        
        while (*p1 && *p2 && *p1 == *p2) {
            p1++; p2++;
        }
        if (*p2 == '\0') return (char *)h;  // 找到完整匹配
    }
    return NULL;  // 未找到
}

演算法複雜度

  • **時間**:O(n×m) 最壞情況 (如 `haystack="aaaaaab"`, `needle="aaab"`)
  • **空間**:O(1)
  • **優化**:KMP (O(n+m))、Boyer-Moore、Sunday、Rabin-Karp (哈希)

3. strcat —— 字串拼接

char *my_strcat(char *dest, const char *src) {
    assert(dest && src);
    
    char *ret = dest;
    
    // 1. 找到 dest 結束符
    while (*dest) dest++;
    
    // 2. 拼接 src (含 \0)
    while ((*dest++ = *src++) != '\0')
        ;
    
    return ret;
}

重疊風險警示

char buf[20] = "hello";
my_strcat(buf, buf + 2);  // 嘗試將 "llo" 拼接到 "hello" 後
// 行為未定義!dest 讀寫位址重疊,可能無限迴圈或記憶體損壞

標準庫保證:`strcat` 行為未定義於重疊。**解決方案**:使用 `memmove` 或手動從後向前複製。

生產級優化:使用標準庫內建

// 現代編譯器會優化為向量化指令 (SSE/AVX/NEON)
char *my_strcpy_opt(char *dest, const char *src) {
    return strcpy(dest, src);  // 直接呼叫 libc 優化版
}

// 或使用 restrict 關鍵字 (C99) 協助編譯器優化
char *my_strcpy_restrict(char *restrict dest, const char *restrict src) {
    // restrict 告訴編譯器 dest/src 不重疊,可積極向量化
    return strcpy(dest, src);
}

常見面試陷阱對比表

函數常見錯誤正確做法
strcpy忘記複製 `\0`、返回值錯誤、無 assert迴圈含 `\0`、返回原 dest、assert 非空
strstr指針回溯邏輯錯、空 needle 未處理雙指針匹配、匹配失敗 h++ 繼續、空 needle 返回 haystack
strcat未找 dest 末尾、緩衝區溢出風險先找 `\0`、呼叫者保證空間足夠

總結

模擬實現核心在於:**指標算術精準控制、const 正確性、邊界條件處理 (空串、NULL)、返回值語義 (支援鏈式)、重疊行為文檔化**。實務開發**直接使用標準庫**,編譯器內建優化 (builtin) 遠超手寫迴圈。面試重點考察:`while (*dest++ = *src++)` 精簡寫法理解、空串處理、重疊未定義行為認知。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved