如何在含动态char*的Passport结构体程序中引入LinkedList
用链表重构你的护照管理程序
嗨,我来帮你把现有的护照管理程序改成基于链表的实现!链表的好处是不用预先限制护照的数量(比如原来的MAX_NUM_PASSPORTS),可以动态添加任意多的条目,灵活性更高。下面是具体的改造步骤和完整代码:
第一步:定义链表节点结构
我们需要一个链表节点结构体,它要包含你的Passport数据,以及一个指向下一个节点的指针:
#include <stdio.h> #include <stdlib.h> #include <string.h> // 先定义Passport结构体(和你原来的一致,优化了变量名) typedef struct passport { char *firstName; // 把冗长的变量名简化,提升可读性 unsigned long long int id; } Passport; // 定义链表节点:包含Passport数据和下一个节点的指针 typedef struct linked_list_node { Passport data; struct linked_list_node *next; } LinkedListNode;
第二步:修改主函数逻辑
原来的代码用动态数组存储多个Passport,现在我们改成用链表头指针来管理,每次新增一个护照就创建一个新节点,加到链表的末尾:
完整修改后的代码
#define MAX_BUFF_SIZE 100 // 补上你原来缺失的缓冲区大小定义 // 实现一个简单的get_input函数(替代你原代码中的自定义函数) void get_input(char *buffer, int max_len) { fgets(buffer, max_len, stdin); // 移除fgets读取到的换行符 buffer[strcspn(buffer, "\n")] = '\0'; } int main() { LinkedListNode *head = NULL; // 链表头指针,初始为空 LinkedListNode *tail = NULL; // 链表尾指针,方便快速添加新节点 int passport_count = 0; // 用来生成递增的护照ID // 这里暂时保留原来的5个限制,你可以改成无限循环直到用户输入终止指令 while (passport_count < 5) { passport_count++; // 1. 为新链表节点分配内存 LinkedListNode *new_node = (LinkedListNode*)malloc(sizeof(LinkedListNode)); if (new_node == NULL) { fprintf(stderr, "Failed to allocate node memory!\n"); exit(1); } // 2. 设置护照ID new_node->data.id = passport_count; // 3. 获取用户输入的名字 char *firstname = (char*)malloc(MAX_BUFF_SIZE * sizeof(char)); if (firstname == NULL) { fprintf(stderr, "Failed to allocate input buffer!\n"); exit(2); } printf("Please enter first name of the owner for Passport with ID=%d: \n", passport_count); get_input(firstname, MAX_BUFF_SIZE - 1); // 4. 为名字分配内存并复制内容 new_node->data.firstName = (char*)malloc(strlen(firstname) + 1); if (new_node->data.firstName == NULL) { fprintf(stderr, "Passport Name Malloc Failed!\n"); free(firstname); free(new_node); exit(3); } strcpy(new_node->data.firstName, firstname); free(firstname); // 临时输入缓冲区用完即释放 // 5. 将新节点添加到链表末尾 new_node->next = NULL; if (head == NULL) { // 链表为空时,头和尾都指向新节点 head = new_node; tail = new_node; } else { // 链表不为空时,尾节点的next指向新节点,更新尾指针 tail->next = new_node; tail = new_node; } } // 遍历链表打印所有护照信息 printf("\n--- All Passport Information ---\n"); LinkedListNode *current = head; while (current != NULL) { printf("Passport id:%llu has been successfully renewed. It belongs to %s\n", current->data.id, current->data.firstName); current = current->next; } // 重要:释放链表所有内存,避免内存泄漏 current = head; while (current != NULL) { LinkedListNode *temp = current; free(current->data.firstName); // 先释放名字的动态内存 current = current->next; free(temp); // 再释放链表节点本身 } return 0; }
关键改动说明
- 链表节点封装:新增
LinkedListNode结构体,把Passport数据和下一个节点的指针绑定,实现动态串联多个条目。 - 高效节点添加:用头指针
head和尾指针tail配合,新增节点时直接加到链表末尾,时间复杂度为O(1)。 - 内存管理优化:添加了完整的内存释放逻辑,修复了原代码中未释放内存的问题;临时输入缓冲区用完后及时释放。
- 修复原代码问题:修正了原代码中循环变量大写
I的错误,补上了缺失的MAX_BUFF_SIZE定义。 - 可读性提升:简化了变量名,让代码更易读。
扩展建议
如果你想让程序更灵活,可以把循环条件改成让用户选择是否继续添加护照(比如输入q退出),这样就完全摆脱固定数量的限制,这也是链表相对于静态/动态数组最大的优势之一。
内容的提问来源于stack exchange,提问作者user14072798
相关产品推荐
相关产品推荐

