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

qsort 回調函數與 void 指針深度解讀:泛型排序的 C 語言實現藝術

     編輯:關於C

經典 K&R qsort 簽名

void qsort(void *v[], int left, int right,
           int (*comp)(void *, void *));

核心設計:類型抹除與回調

  • void *v[]:任意指針陣列,元素大小固定為指針寬度(4/8 位元組)
  • comp:使用者提供具體類型比較邏輯,在回調內完成強制轉型
  • 排序演算法本身完全不知曉元素真實類型,僅搬運指針

為何能這樣轉型?

  1. 任意指針隱式轉換為 void*
  2. void* 可顯式轉換回目標指針類型
  3. 所有指針在同一平台佔用相同位元組數,指針運算(加減/比較/賦值)不需知道指向類型
  4. 關鍵限制:qsort 內部絕不解引用 void* 做算術/邏輯運算,僅做指針搬移

實戰:字串指針陣列排序

int str_cmp(void *a, void *b) {
    return strcmp(*(char**)a, *(char**)b); // 解引用兩次拿到 char*
}

char *fruits[] = {"banana", "apple", "pear", "orange"};
qsort((void**)fruits, 0, 3, str_cmp);
// 結果:apple, banana, orange, pear

泛型交換輔助函數

void swap(void *v[], int i, int j) {
    void *tmp = v[i];
    v[i] = v[j];
    v[j] = tmp;
}

避坑指南

  1. 比較函數必須正確處理 const 與多級指針轉型
  2. 傳遞陣列時需強轉 (void**),否則編譯器警告
  3. 結構體排序時,比較函數接收 struct T*,轉型為 const struct T*
  4. 嚴禁在 qsort 內對 void* 做 sizeof、算術運算

現代替代:C11 qsort_s / C++ std::sort

  • qsort_s 增加上下文指針,避免全域變量傳遞比較參數
  • C++ 模板實現零開銷泛型,型別安全,內聯優化更快
  • 嵌入式 C 專案仍以經典 qsort 為主流
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved