如何传递结构体成员作为函数参数,精简排序函数数量?
解决方案:用函数指针实现通用排序
核心思路是把排序逻辑和成员比较逻辑分离:写一个通用的冒泡排序函数,将结构体成员的比较规则以函数指针的形式传入,无需为每个成员的升/降序单独编写完整排序函数。
第一步:定义比较函数类型
先声明统一的函数指针类型,规则和标准库qsort的比较函数一致——返回负数/0/正数分别表示第一个参数小于/等于/大于第二个参数:
#include <string.h> // 用于字符串比较的strcmp // 定义比较函数的指针类型 typedef int (*CompareFunc)(const struct propertySales*, const struct propertySales*);
第二步:实现通用排序函数
提取冒泡排序的核心逻辑,接受待排序数组、元素个数、比较函数作为参数:
void generic_sort(struct propertySales arr[], int count, CompareFunc cmp) { for (int i = 0; i < count - 1; i++) { for (int j = 0; j < count - i - 1; j++) { // 根据比较函数结果判断是否交换:若arr[j] "大于" arr[j+1]则交换 if (cmp(&arr[j], &arr[j+1]) > 0) { struct propertySales temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } }
第三步:为每个结构体成员编写比较函数
针对不同类型的成员编写升序比较函数,降序只需反转升序函数的返回值即可:
1. 日期(tanggal)比较
假设tanggal[0]为日、tanggal[1]为月、tanggal[2]为年,按年→月→日的优先级比较:
// 日期升序 int compare_tanggal_asc(const struct propertySales* a, const struct propertySales* b) { if (a->tanggal[2] != b->tanggal[2]) return a->tanggal[2] - b->tanggal[2]; if (a->tanggal[1] != b->tanggal[1]) return a->tanggal[1] - b->tanggal[1]; return a->tanggal[0] - b->tanggal[0]; } // 日期降序(反转升序结果) int compare_tanggal_desc(const struct propertySales* a, const struct propertySales* b) { return -compare_tanggal_asc(a, b); }
2. 字符串类型成员(pelanggan、jenisProperty、namaProperty)
用strcmp实现字符串比较:
// 客户名称升序 int compare_pelanggan_asc(const struct propertySales* a, const struct propertySales* b) { return strcmp(a->pelanggan, b->pelanggan); } // 客户名称降序 int compare_pelanggan_desc(const struct propertySales* a, const struct propertySales* b) { return -strcmp(a->pelanggan, b->pelanggan); } // 复制上述逻辑,修改成员名即可得到jenisProperty、namaProperty的比较函数 int compare_jenisProperty_asc(const struct propertySales* a, const struct propertySales* b) { return strcmp(a->jenisProperty, b->jenisProperty); } int compare_jenisProperty_desc(const struct propertySales* a, const struct propertySales* b) { return -compare_jenisProperty_asc(a, b); } int compare_namaProperty_asc(const struct propertySales* a, const struct propertySales* b) { return strcmp(a->namaProperty, b->namaProperty); } int compare_namaProperty_desc(const struct propertySales* a, const struct propertySales* b) { return -compare_namaProperty_asc(a, b); }
3. 整数类型成员(jumlahProperty)
直接通过差值判断大小:
// 数量升序 int compare_jumlahProperty_asc(const struct propertySales* a, const struct propertySales* b) { return a->jumlahProperty - b->jumlahProperty; } // 数量降序 int compare_jumlahProperty_desc(const struct propertySales* a, const struct propertySales* b) { return -compare_jumlahProperty_asc(a, b); }
4. 浮点类型成员(hargaProperty、totalPembayaran)
浮点类型不能直接用差值判断,需通过大于/小于比较:
// 单价升序 int compare_hargaProperty_asc(const struct propertySales* a, const struct propertySales* b) { if (a->hargaProperty < b->hargaProperty) return -1; else if (a->hargaProperty > b->hargaProperty) return 1; return 0; } // 单价降序 int compare_hargaProperty_desc(const struct propertySales* a, const struct propertySales* b) { return -compare_hargaProperty_asc(a, b); } // 总金额升序 int compare_totalPembayaran_asc(const struct propertySales* a, const struct propertySales* b) { if (a->totalPembayaran < b->totalPembayaran) return -1; else if (a->totalPembayaran > b->totalPembayaran) return 1; return 0; } // 总金额降序 int compare_totalPembayaran_desc(const struct propertySales* a, const struct propertySales* b) { return -compare_totalPembayaran_asc(a, b); }
第四步:调用通用排序函数
替代原有14个排序函数,只需在调用时指定对应的比较函数即可,比如你原本的sort_totalPembayaran_descending可以替换为:
void sort_totalPembayaran_descending() { int currentIndex = index_counter(); generic_sort(compare, currentIndex, compare_totalPembayaran_desc); system("cls"); printf("Sorting berdasarkan total pembayaran (Descending)\n"); print_column(); print_data(compare); }
如果需要进一步简化,还可以封装一个通用的排序+打印函数,避免重复编写清屏、打印逻辑。
内容的提问来源于stack exchange,提问作者Raynaldy Dwi
相关产品推荐
相关产品推荐

