传递struct的字段名称以访问函数内部

我有一个链表,我做了一个获取节点的function。 但我想用它来搜索名字或姓氏。

typedef struct people { char name[60], lastname[60]; struct people *next; } people; people *search(const char *key, people *list, FIELD) { while (list && strcmp(key, list->FIELD) != 0) { list = list->next; } return list; } 

例:

 people *aux; aux = search("John", list_of_people, "name"); 

要么:

 aux = search("Smith", list_of_people, "lastname"); 

有一种清晰有效的方法来解决这个问题而不重复代码?

使用offsetof()宏。

例如:

 people *search(const char *key, people *list, size_t FIELD) {// FIELD is field offset, while (list && strcmp(key, (char*)list + FIELD) != 0) { list = list->next; } return list; } 

呼叫

 aux = search("John", list_of_people, offsetof(people, name)); aux = search("Smith", list_of_people, offsetof(people, lastname)); 

只有两个字段,这似乎是显而易见的方式:

 people *search(const char *key, people *list, bool first) { while (list && strcmp(key, first ? list->name : list->lastname) != 0) { list = list->next; } return list; } 

对于更一般的情况,这样的事情会起作用:

 struct mystruct { char field1[60]; char field2[60]; char field3[60]; char field4[60]; char field5[60]; struct mystruct * next; } char * get_field(struct mystruct * list, size_t field) { char * fields[] = { list->field1, list->field2, list->field3, list->field4, list->field5 }; return fields[field]; } people *search(const char *key, people *list, bool first) { while (list && strcmp(key, get_field(list, 3)) != 0) { list = list->next; } return list; } 

我建议使用enum来进行不同的搜索。

 enum {SEARCH_BY_FIRSTNAME, SEARCH_BY_LASTNAME}; char* getSeachName(people* list, int searchBy) { return ( searchBy == SEARCH_BY_FIRSTNAME ? list->name : list->lastname ); } people *search(const char *key, people *list, int searchBy) { while (list && strcmp(key, getSearchName(list, searchBy)) != 0) { list = list->next; } return list; } // Search by first name. people *aux; aux = search("John", list_of_people, SEARCH_BY_FIRSTNAME); // Search by last name. aux = search("Smith", list_of_people, SEARCH_BY_LASTNAME);