C语言链表动态结构:检查人员存在及addHuman函数修复
问题修复与人员存在检查方案
一、检查指定人员是否存在(实现findHuman函数)
要检查链表中是否存在指定人员,核心逻辑是遍历链表的每个节点,对比节点的name和surname与目标值是否完全匹配。以下是findHuman的实现代码:
#include <string.h> // 依赖strcmp字符串比较函数 Human *findHuman(List *list, char *name, char *surname) { // 链表为空或无效时直接返回NULL if (list == NULL || list->head == NULL) { return NULL; } Human *current = list->head; while (current != NULL) { // 同时匹配名字和姓氏,完全一致才返回该节点 if (strcmp(current->name, name) == 0 && strcmp(current->surname, surname) == 0) { return current; } current = current->next; } return NULL; // 遍历完毕未找到匹配人员 }
注:这里假设你使用的
List结构体定义如下(如果你的List结构不同,请对应调整遍历逻辑):typedef struct List { Human *head; Human *tail; // 可选,用于快速追加节点 } List;
二、修复addHuman函数的问题
你的addHuman代码存在多处关键错误,逐一修复如下:
1. 移除冗余的函数声明
函数定义开头的void addHuman(List *list, char *name, char *surname, Human *father, Human *mother);是多余的声明,直接删除该行。
2. 检查内存分配结果
malloc可能分配失败并返回NULL,必须添加检查避免后续操作空指针:
Human *new = (Human *) malloc(sizeof(Human)); if (new == NULL) { printf("Error: Failed to allocate memory\n"); return; }
3. 安全处理字符串拷贝
strcpy不检查缓冲区大小,若输入的名字/姓氏长度超过50会导致溢出,改用strncpy并手动添加字符串结束符:
strncpy(new->name, name, sizeof(new->name) - 1); new->name[sizeof(new->name) - 1] = '\0'; // 确保字符串正常终止 strncpy(new->surname, surname, sizeof(new->surname) - 1); new->surname[sizeof(new->surname) - 1] = '\0';
4. 将新节点接入链表
当前代码仅创建了节点,但未将其链接到链表中,会导致节点丢失。根据链表类型选择接入方式:
- 头插法(新节点作为链表头部):
new->next = list->head; list->head = new;
- 尾插法(新节点追加到链表尾部,需
List包含tail指针):
new->next = NULL; if (list->head == NULL) { // 链表为空时,头尾都指向新节点 list->head = new; list->tail = new; } else { list->tail->next = new; list->tail = new; }
5. 完整修复后的addHuman函数
#include <stdio.h> #include <stdlib.h> #include <string.h> void addHuman(List *list, char *name, char *surname, Human *father, Human *mother) { // 检查链表指针是否有效 if (list == NULL) { printf("Error: List is NULL\n"); return; } // 检查人员是否已存在 Human *existingHuman = findHuman(list, name, surname); if (existingHuman != NULL) { printf("Person exists already.\n"); return; } // 分配内存并检查结果 Human *new = (Human *) malloc(sizeof(Human)); if (new == NULL) { printf("Error: Failed to allocate memory for new human\n"); return; } // 安全拷贝名字与姓氏 strncpy(new->name, name, sizeof(new->name) - 1); new->name[sizeof(new->name) - 1] = '\0'; strncpy(new->surname, surname, sizeof(new->surname) - 1); new->surname[sizeof(new->surname) - 1] = '\0'; // 设置父母指针 new->mother = mother; new->father = father; // 将新节点接入链表(此处使用尾插法) new->next = NULL; if (list->head == NULL) { list->head = new; list->tail = new; } else { list->tail->next = new; list->tail = new; } }
额外注意事项
- 若你的
List结构体仅包含head指针,尾插法需要遍历到链表末尾,效率较低,此时头插法会更简便。 - 若输入的
name或surname可能为NULL,需在函数开头添加空指针检查,避免strncpy触发错误。
内容的提问来源于stack exchange,提问作者Eileen_Ilyn
相关产品推荐
相关产品推荐

