字串大小比較遵循字典序 (Lexicographical Order):逐字元比較 ASCII 碼值,首個差異決定大小;若前綴完全相同,較短者視為較小 (因隱含結束符 '\0' = 0)。
1 :str1 > str20 :str1 == str2-1 :str1 < str2zstrncmp// 比較前 num 個字元,或直到遇到 '\0'
char zstrncmp(const unsigned char *str1, const unsigned char *str2, unsigned char num)
{
while (num-- != 0) {
if (*str1 == *str2) {
if (*str1 == '\0') return 0; // 同為結束符,相等
str1++; str2++;
} else if (*str1 > *str2) {
return 1;
} else {
return -1;
}
}
return 0; // 前 num 字元完全相同
}
關鍵點:
unsigned char 避免負值擴展導致錯誤比較 (如延伸 ASCII 字元)。'\0' 可正確處理「一字串是另一字串前綴」的情況。char 足夠容納 -1/0/1,但標準庫慣用 int。strcmp 與 strncmp#include <string.h>
int strcmp(const char *s1, const char *s2); // 比較至 '\0'
int strncmp(const char *s1, const char *s2, size_t n); // 比較前 n 字元
回傳值語義:<0、0、>0 (非固定 -1/1),具體差值為首個不同字元的 unsigned char 差值。
const char *a = "apple", *b = "banana";
if (strcmp(a, b) < 0) printf("%s 排在 %s 前面\n", a, b); // 真
// 僅比較前 3 字元
if (strncmp("abcdef", "abcxyz", 3) == 0) puts("前綴相同");
控制字元 (0-31) < 空格 (32) < 數字 '0'-'9' (48-57)
< 大寫 'A'-'Z' (65-90) < 部分符號 < 小寫 'a'-'z' (97-122)
因此:"Apple" < "apple" (大寫 A=65 < 小寫 a=97),"2" < "10" (字元 '2'=50 > '1'=49,但字典序逐字元比較,'2' > '1' 所以 "2" > "10")。
char c = 0xFF; // 若 char 有號,值為 -1
if (c > 'a') ... // 錯誤:-1 < 'a'
// 修正:轉為 unsigned char 比較
if ((unsigned char)c > 'a') ...
標準庫 strcmp 內部已轉換為 unsigned char 比較,自定義函數務必同樣處理。
strcoll、strxfrm 依當前 LC_COLLATE 進行語言感知排序 (如德語 ß 視為 ss),但效能較差。純 ASCII/UTF-8 位元組序比較請用 strcmp/memcmp。
'\0' 結束。strncmp 限制最大比較長度。size_t 或 SIMD (SSE/AVX) 批量比較 8/16/32 位元組。__builtin_strcmp、__builtin_memcmp 可自動向量化。int cmp_str(const void *a, const void *b) {
return strcmp(*(const char **)a, *(const char **)b);
}
const char *arr[] = {"delta", "alpha", "epsilon", "beta", "gamma"};
qsort(arr, 5, sizeof(char *), cmp_str);
// 結果:alpha, beta, delta, epsilon, gamma
| 需求 | 推薦函數 | 備註 |
|---|---|---|
| 一般字串相等/大小 | strcmp | 最常用,標準庫高度優化 |
| 限制比較長度 / 二進制資料 | strncmp / memcmp | memcmp 不看 '\0',適合含零字元資料 |
| 語言感知排序 (人類語序) | strcoll | 較慢,需 setlocale |
| 嵌入式/教學/特殊邏輯 | 自定義 zstrncmp | 掌握核心邏輯,注意 unsigned char 轉換 |
理解字串比較的字典序本質、ASCII 碼序、結束符語義、有號字元陷阱,能避開 90% 的排序與比較 Bug。