You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 07:47:50