如何为结构体中的指定字段使用通用比较函数?
问题描述
假设有如下结构体:
struct Person { int age; int weight; int height; };
我希望实现一个通用比较函数,接收两个Person结构体实例,根据指定字段进行比较。设想的比较函数如下:
int compare(void *first_data, void *second_data, void *param) { if (first_data->param > second_data->param) { return -1; } if (first_data->param < second_data->param) { return 1; } return 0; }
其中void *first_data和void *second_data分别代表两个Person实例,void *param用于指定比较的字段。目前不清楚如何利用void *param实现该功能,比如如何按weight字段比较两个实例?
实现方案
核心思路是利用结构体字段的偏移量指定要比较的字段,C语言中可通过offsetof宏获取结构体成员相对于结构体起始地址的偏移字节数,以此实现通用比较。
1. 修正比较函数实现
将param作为字段偏移量使用,通过指针计算定位到目标字段并取值比较:
#include <stddef.h> // 引入offsetof宏所需头文件 int compare(void *first_data, void *second_data, void *param) { size_t field_offset = (size_t)param; // 计算目标字段地址并取值 int first_val = *(int*)((char*)first_data + field_offset); int second_val = *(int*)((char*)second_data + field_offset); if (first_val > second_val) return -1; if (first_val < second_val) return 1; return 0; }
2. 调用示例(按weight字段比较)
传入offsetof(struct Person, weight)作为param参数,即可指定按weight字段比较:
#include <stdio.h> int main() { struct Person p1 = {25, 70, 175}; struct Person p2 = {30, 65, 180}; // 按weight字段比较两个Person实例 int result = compare(&p1, &p2, (void*)offsetof(struct Person, weight)); if (result == -1) printf("p1的weight大于p2\n"); else if (result == 1) printf("p1的weight小于p2\n"); else printf("p1和p2的weight相等\n"); return 0; }
关键原理说明
offsetof(struct Person, weight)返回weight字段相对于struct Person起始地址的字节偏移量(比如age占4字节时,weight偏移量为4)。- 将
first_data转为char*是因为char大小为1字节,加上偏移量后能精准定位到目标字段地址,再转为int*即可取出字段值完成比较。
内容的提问来源于stack exchange,提问作者Evgeni Pogoster
相关产品推荐
相关产品推荐

