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

C 語言字符串複製函數全解析:strcpy、strncpy、memcpy、memmove 深度對比

     編輯:關於C語言

C 語言字符串複製函數全解析:strcpy、strncpy、memcpy、memmove 深度對比

C 標準庫提供四種字符串/記憶體複製函數:strcpy、strncpy、memcpy、memmove。它們在複製行為、空字符(\0)處理、重疊記憶體安全性上有顯著差異。本文通過實例與記憶體地址分析,深度剖析各函數特性與最佳實踐。

一、 四大複製函數原型與核心差異

函數原型複製單位遇 \0 停止補 \0重疊安全
strcpychar *strcpy(char *s1, const char *s2)字符是是(複製含 \0)否
strncpychar *strncpy(char *s1, const char *s2, size_t n)字符否(固定 n)不足 n 補 \0否(舊標準)
memcpyvoid *memcpy(void *s1, const void *s2, size_t n)位元組否否否(舊標準)
memmovevoid *memmove(void *s1, const void *s2, size_t n)位元組否否是

二、 strcpy:簡單但危險

strcpy(s1, s2) 複製含結尾 \0 的整串字符。若 s1 空間不足,會溢出覆蓋後續記憶體(「躺槍」現象)。

實例:s1(8 位元組)複製 s2(11 字符),超出 3 字節污染緊鄰的 s3。

三、 strncpy:長度可控,但有坑

strncpy(s1, s2, n) 複製前 n 字符:

  • s2 長度 ≥ n:不補 \0,s1 非合法字符串,輸出時會讀到後續記憶體。
  • s2 長度 < n:複製完 s2 後,補 \0 至 n 字節。

最佳實踐:n = sizeof(s1) - 1,複製後手動 s1[n] = '\0'。

四、 memcpy:泛型位元組複製

行為同 strncpy(固定 n 字節,不關心 \0),但適用於任意類型資料(結構體、陣列等),非字符串專用。

五、 memmove:重疊記憶體的安全選擇

當 s1 與 s2 記憶體區域重疊時,strcpy、strncpy、memcpy 行為未定義(舊標準)。memmove 內部處理重疊(如由後向前複製),保證正確。

實例驗證:strcpy(s2, s2+1) 結果異常;memmove(s2, s2+1, n) 正確右移字符串。

注:現代 C 庫(glibc 等)已優化 strncpy/memcpy 支援重疊,但標準未保證,跨平台仍首選 memmove。

六、 總結與選擇指南

  • 字符串複製,確保目標足夠大:strcpy 或 strncpy + 手動加 \0。
  • 字符串複製,目標空間受限:strncpy(dest, src, sizeof(dest)-1); dest[sizeof(dest)-1] = '\0';
  • 非字符串資料(結構體、二進制):memcpy(非重疊)或 memmove(可能重疊)。
  • 不確定是否重疊:直接用 memmove,性能差異可忽略。

標準庫函數的演進體現了「先收錄廣泛使用的舊函數,再提供改進版」的務實哲學。理解其歷史包袱與設計權衡,才能寫出健壯、可移植的 C 代碼。

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