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

C語言string.h核心函數速查手冊:內存與字符串操作完整指南

     編輯:關於C

內存操作函數(不關心字符串結構)

函數原型語義關鍵區別
memcpyvoid *memcpy(void *dest, const void *src, size_t n)拷貝n字節,src與dest不得重疊最快,無重疊檢查
memmovevoid *memmove(void *dest, const void *src, size_t n)拷貝n字節,正確處理重疊內部自動判斷方向拷貝
memsetvoid *memset(void *s, int c, size_t n)將s前n字節置為c(轉unsigned char)清零結構體/數組首選
memcmpint memcmp(const void *s1, const void *s2, size_t n)比較前n字節,返回<0/=0/>0按無符號字節比較

字符串操作函數(以\0結束)

函數原型語義返回值
strcpychar *strcpy(char *dest, const char *src)拷貝含\0的字符串,dest不可重疊dest
strncpychar *strncpy(char *dest, const char *src, size_t n)拷貝最多n字符,不足補\0,可能無\0結尾dest
strcatchar *strcat(char *dest, const char *src)追加src到dest末尾,dest空間需足夠dest
strncatchar *strncat(char *dest, const char *src, size_t n)追加src前n字符,保證\0結尾dest
strcmpint strcmp(const char *s1, const char *s2)字典序比較(ASCII值),至\0或差異處<0/=0/>0
strncmpint strncmp(const char *s1, const char *s2, size_t n)比較前n字符<0/=0/>0
strchrchar *strchr(const char *s, int c)查找字符c首次出現位置指針/NULL
strrchrchar *strrchr(const char *s, int c)查找字符c最後一次出現位置指針/NULL
strstrchar *strstr(const char *haystack, const char *needle)查找子串首次出現指針/NULL
strlensize_t strlen(const char *s)計算字符串長度(不含\0)長度

大小寫不敏感比較(POSIX擴展)

int strcasecmp(const char *s1, const char *s2);      // 全長比較
int strncasecmp(const char *s1, const char *s2, size_t n); // 前n字符

安全編程紅黑榜

✅ 推薦使用
  • snprintf(dest, size, fmt, ...) —— 有界格式化輸出
  • strncpy_s / strcat_s / sprintf_s (C11 Annex K / MSVC) —— 邊界檢查版
  • memmove 替代 memcpy 當重疊可能性>0時
  • 自定義strlcpy/strlcat (BSD風格) —— 保證\0結尾,返回源長度
❌ 禁用/慎用
  • gets —— 無邊界檢查,C11已移除
  • strcpy/strcat/sprintf —— 緩衝區溢出溫床
  • strncpy —— 易導致無\0結尾字符串,後續操作崩潰
  • strtok —— 非線程安全,修改源字符串,改用strtok_r

常見陷阱實例

// 陷阱1:strncpy不保證\0結尾
char buf[8];
strncpy(buf, "12345678", 8); // buf = {'1','2','3','4','5','6','7','8'} 無\0!
printf("%s", buf); // UB:讀越界直到隨機遇到\0
// 修正:
buf[sizeof(buf)-1] = '\0'; // 強制終止
// 或用 snprintf(buf, sizeof(buf), "%s", src);

// 陷阱2:strcmp返回值誤判
if (strcmp(a, b)) // ❌ 相等返回0(假),不等返回非0(真) —— 邏輯反了
if (strcmp(a, b) == 0) // ✅ 相等
if (strcmp(a, b) != 0) // ✅ 不等

// 陷阱3:memset非字節填充
int arr[10];
memset(arr, 1, sizeof(arr)); // ❌ 每字節置1 → 0x01010101 = 16843009
// 正確:循環賦值或用填充函數

性能提示

  • memcpy/memset通常優化為SIMD指令(SSE/AVX/NEON),對齊內存時極快
  • 小塊拷貝(<64B)編譯器常內聯為指令序列,無函數調用開銷
  • 字符串函數難以向量化(\0終止不定長),長字符串考慮手寫SIMD或strlen先算長再memcpy
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved