在 C 語言開發中,內存比較是常見操作。標準庫提供了 memcmp、strcmp、strncmp 三個函數,雖然功能相似,但適用場景與行為差異巨大。本文將從底層實現角度出發,帶你手寫 memcmp,並深度對比三者區別,助你精準選型。
memcmp 是「內存比較」函數,按字節逐個比較兩塊內存區域,不以 \0 為終止條件,需顯式指定比較長度 count。返回值規則:相等返回 0,前者大返回正數,否則返回負數。
以下是模擬實現代碼,採用 const void* 通用指針,轉為 char* 逐字節比對:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int my_memcmp(const void *p1, const void *p2, size_t count) {
assert(p1);
assert(p2);
char *dest = (char *)p1;
char *src = (char *)p2;
while (count && *dest == *src) {
count--;
dest++;
src++;
}
if (count == 0) return 0;
return *dest - *src;
}
int main() {
char arr1[] = "hello";
char arr2[] = "hello world";
int len = sizeof(arr1) / sizeof(arr1[0]); // 含結束符共 6 字節
int ret = my_memcmp(arr1, arr2, 12); // 故意超長比較,觀察行為
printf("%d", ret);
system("pause");
return 0;
}
| 特性 | memcmp | strcmp | strncmp |
|---|---|---|---|
| 比較對象 | 任意內存區塊 | 以 \0 結尾的字符串 | 字符串,但限制前 n 字符 |
| 終止條件 | count 歸零或遇到差異字節 | 任一字符串遇到 \0 | 遇到 \0、差異、或已比較 n 字符 |
| 典型用途 | 結構體、數組、二進制數據比較 | 完整字符串相等性判斷 | 前綴匹配、固定長度字符串比較 |
| 安全隱患 | 越界讀取導致崩潰 | 缺少長度限制,隱患較大 | 較安全,但需確保 n 不超實際長度 |
memcmp 逐字節比對,浮點數存在 +0.0/-0.0、NaN 等特殊位模式,直接比較結果不可靠;結構體可能含填充字節,導致誤判。建議逐字段比較。strcmp;需限制長度(如網絡協議解析)用 strncmp。qsort/bsearch 回調時,整數類型切勿直接相減(溢出風險),應用三元運算符:return (*a > *b) - (*a < *b);理解 memcmp、strcmp、strncmp 的本質區別,能讓你在處理二進制數據、字符串解析、排序比較等場景時游刃有餘。記住:內存比較看字節,字符串比較看 \0,長度限制保平安。