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

memcpy 兩種實現:標準逐字節 vs Duff's Device 解卷優化

     編輯:關於C語言

版本一:標準逐字節拷貝(教科書級)

void* memcpy(void* dest, const void* src, size_t count) {
    if (count == 0) return dest;
    if (!dest || !src) return NULL;
    if (dest == src) return dest;

    char* d = (char*)dest;
    const char* s = (const char*)src;
    while (count--)
        *d++ = *s++;
    return dest;
}

關鍵點:

  • 參數驗證(空指針、自拷貝)
  • 轉 char* 按位元組操作
  • 返回 dest 支援鏈式調用

版本二:Duff's Device(循環解卷,每輪 8 字節)

void* mymemcpy(void* dest, const void* src, size_t count) {
    char* d = (char*)dest;
    const char* s = (const char*)src;
    int n = (count + 7) / 8;  // 輪數(向上取整)

    switch (count & 7) {      // 餘數決定跳入位置
        case 0: do { *d++ = *s++;
        case 7:      *d++ = *s++;
        case 6:      *d++ = *s++;
        case 5:      *d++ = *s++;
        case 4:      *d++ = *s++;
        case 3:      *d++ = *s++;
        case 2:      *d++ = *s++;
        case 1:      *d++ = *s++;
        } while (--n > 0);
    }
    return dest;
}

原理解析

  • count = 9 → n = 2、count & 7 = 1 → 跳入 case 1 執行 1 次,while 再跑 1 輪 8 次,共 9 次。
  • 核心優化:每 8 字節減 7 次分支跳轉(AMD 預測器假設全跳,省時鐘週期)。
  • 現代 CPU 配合 SIMD(SSE/AVX/NEON)每指令 16/32/64 字節,手寫 Duff's Device 已非最優。

面試/考試必考檢查清單

  1. const void* src — 防止誤修改源數據
  2. 另用局部指針 d/s 操作,不動原參數
  3. void* → char* 類型轉換正確
  4. 檢查 dest == src 自拷貝
  5. 檢查空指針
  6. 返回 dest

補充:strcpy 參數 const 正確性

char* strcpy(char* strDest, const char* strSrc) {
    assert(strDest && strSrc);
    char* addr = strDest;
    while ((*strDest++ = *strSrc++) != '\0');
    return addr;
}

const char* strSrc 限定的是指向內容不可變,而非指針本身。函數內 strSrc++ 修改的是形參副本,不影響實參指向的字符串常量,安全合法。

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