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

C語言手寫 strcpy:面試必考的字串複製函式完美實作

     編輯:關於C

面試官為何愛考 strcpy?

`strcpy` 看似簡單,實則考察三大核心能力:

  1. 程式碼風格:簡潔、可讀、符合慣用語。
  2. 錯誤處理:空指標檢查、緩衝區溢位防護。
  3. 效能與介面設計:鏈式呼叫支援、`const` 正確性、避免重複計算。

標準庫規格回顧

char *strcpy(char *dest, const char *src);
// 複製 src 字串(含結束符 \0)到 dest
// 回傳 dest 指標,支援鏈式呼叫
// 行為未定義:dest 空間不足、src/dest 重疊

最佳實作版本

#include 

char *my_strcpy(char *dest, const char *src) {
    // 1. 斷言檢查(Debug 版攔截,Release 版零開銷)
    assert(dest != NULL && src != NULL);

    // 2. 保存原始 dest 以便回傳(鏈式呼叫關鍵)
    char *ret = dest;

    // 3. 經典單行複製迴圈:賦值與判斷合併
    //    *dest++ = *src++ 先解參考賦值,再遞增指標
    //    結果為賦值後的字元值,\0 為 0 (false) 結束迴圈
    while ((*dest++ = *src++)) ;

    // 4. 回傳原始目的地址
    return ret;
}

逐行深度解析

程式碼解析
`assert(dest && src)`防禦性程式設計,捕捉空指標傳入。生產碼可改為 `if (!dest || !src) return NULL;`
`char *ret = dest;`因 `dest` 會在迴圈中遞增至末尾,必須保存起始位址供回傳。
`while ((*dest++ = *src++)) ;`C 語言經典慣用語:賦值運算式的值為賦值結果。複製 `\0` 時值為 0,迴圈結束。分號代表空迴圈體。
`return ret;`支援 `printf("%s", my_strcpy(buf, "hello"));` 等鏈式呼叫。

進階版:安全版 strcpy_s / strncpy 風格

// 回傳 0 成功,非 0 失敗
errno_t strcpy_s(char *dest, size_t destsz, const char *src) {
    if (!dest || !src || destsz == 0) return EINVAL;
    char *d = dest;
    const char *s = src;
    while (destsz-- && (*d++ = *s++)) ;
    if (destsz == 0) { *dest = '\0'; return ERANGE; } // 空間不足
    return 0;
}

常見面試陷阱題

  1. 重疊記憶體複製:`strcpy(buf+2, buf)` 行為未定義。正確用 `memmove`。
  2. 缺少 `const`:`char *strcpy(char *dest, char *src)` 允許修改來源字串,違反語意。
  3. 忘記回傳值:無法鏈式呼叫,違反標準規格。
  4. 使用 `strlen` + `memcpy`:掃描兩次字串,效率較單次掃描低。

同場加映:手寫 strlen

size_t my_strlen(const char *s) {
    assert(s);
    const char *p = s;
    while (*p) p++;
    return p - s; // 指標相減得元素個數
}

總結:完美 strcpy 條件清單

  • [ ] 參數 `const` 正確性
  • [ ] 空指標斷言/檢查
  • [ ] 單次掃描複製(含 `\0`)
  • [ ] 回傳原始 `dest` 支援鏈式呼叫
  • [ ] 註解說明行為未定義情況(重疊、空間不足)
  • [ ] 無多餘變數、無分支預測失誤

結語

手寫 `strcpy` 不只是背誦程式碼,而是展現對 C 語言指標算術、運算式求值順序、標準庫契約、防禦性程式設計的綜合掌握。面試時寫出上述版本並能娓娓道來每一行設計理由,即為通關關鍵。

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