需求分析與原型確定
- 拷貝任意類型數據 →
void*
- 源數據只讀 →
const void*
- 需指定拷貝字節數 →
size_t n
- 返回目標地址便於鏈式調用 →
void*
void *memcpy(void *dest, const void *src, size_t n);
錯誤處理考量
- 空指針檢查:
dest==NULL || src==NULL → 返回 NULL
- 計數異常:
n==0 → 直接返回 dest (標準行為)
- 目標空間足夠:**無法在函數內保證**,屬調用者責任
- 內存重疊:
memcpy **未定義行為**,重疊用 memmove
逐字節實現 (教學版)
void *memcpy(void *dest, const void *src, size_t n) {
if (!dest || !src) return NULL;
char *d = (char*)dest;
const char *s = (const char*)src;
// 保存原始 dest 用於返回
void *ret = dest;
while (n--) *d++ = *s++;
return ret;
}
常見面試錯誤與修正
| 錯誤代碼 | 問題 | 修正 |
return dest; (循環後) | dest 已遞增指向末尾 | 保存 void *ret = dest; 循環前 |
while(n--) *dest++ = *src++; | void* 不能算術運算 | 轉 char* 後操作 |
if (n <= 0) return NULL; | size_t 無符號,n==0 合法 | if (n == 0) return dest; |
生產級優化策略
- 字對齊拷貝:按
sizeof(long) 或 SIMD (SSE/AVX/NEON) 批量拷貝
- 方向優化:
dest < src 正向,dest > src 逆向 (避免重疊時覆蓋源數據,雖 memcpy 不保證)
- 小塊優化:
n < 16 用展開循環
標準庫實現參考 (glibc 簡化)
void *memcpy(void *dest, const void *src, size_t n) {
if (!n) return dest;
// 對齊處理、大塊 vectorized 拷貝、尾部字節拷貝...
return dest;
}
面試回答要點
- 先給標準原型,說明各參數含義
- 列出錯誤處理:空指針、零長度
- 給出正確逐字節實現 (保存返回值、轉 char*)
- 補充:重疊用
memmove,優化思路 (對齊、SIMD、方向)
- 強調
restrict 關鍵字 (C99) 告訴編譯器不重疊
- 上一篇文章: C 語言學習筆記 (三):函數參數求值、const/static、大小端判斷、指針與數組深度解析
- 下一篇文章: 雙船裝貨問題:背包問題變體的子集樹窮舉與位運算優化
Copyright ©
程式碼之家 All Rights Reserved