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

C 語言字串比較大小:自定義實現與標準庫最佳實務

     編輯:關於C語言

比較邏輯定義

字串大小比較遵循字典序 (Lexicographical Order):逐字元比較 ASCII 碼值,首個差異決定大小;若前綴完全相同,較短者視為較小 (因隱含結束符 '\0' = 0)。

  • 回傳 1 :str1 > str2
  • 回傳 0 :str1 == str2
  • 回傳 -1 :str1 < str2

自定義實現:長度限制版 zstrncmp

// 比較前 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("前綴相同");

ASCII 碼序關鍵順序 (常見字元)

控制字元 (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")。

常見陷阱與最佳實務

1. 字元有號性陷阱

char c = 0xFF; // 若 char 有號,值為 -1
if (c > 'a') ... // 錯誤:-1 < 'a'

// 修正:轉為 unsigned char 比較
if ((unsigned char)c > 'a') ...

標準庫 strcmp 內部已轉換為 unsigned char 比較,自定義函數務必同樣處理。

2. 區域設定 影響

strcoll、strxfrm 依當前 LC_COLLATE 進行語言感知排序 (如德語 ß 視為 ss),但效能較差。純 ASCII/UTF-8 位元組序比較請用 strcmp/memcmp。

3. 安全性:避免緩衝區溢位

  • 確保字串以 '\0' 結束。
  • 輸入來源不可信時,優先使用 strncmp 限制最大比較長度。

4. 效能微優化

  • 對齊記憶體存取:以 size_t 或 SIMD (SSE/AVX) 批量比較 8/16/32 位元組。
  • 編譯器內建:__builtin_strcmp、__builtin_memcmp 可自動向量化。

進階:自定義比較器 (qsort/bsearch 回調)

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 / memcmpmemcmp 不看 '\0',適合含零字元資料
語言感知排序 (人類語序)strcoll較慢,需 setlocale
嵌入式/教學/特殊邏輯自定義 zstrncmp掌握核心邏輯,注意 unsigned char 轉換

理解字串比較的字典序本質、ASCII 碼序、結束符語義、有號字元陷阱,能避開 90% 的排序與比較 Bug。

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