C语言链表打印时头部莫名出现0的问题排查求助
问题分析与修复方案
核心问题根源
未初始化的头节点导致首个值为0
原代码中allocMem函数创建链表时,直接malloc了一个USER节点,但未给number字段赋值,该节点会作为链表首个元素,其值是未初始化的垃圾值(此处恰好显示为0)。后续添加的节点都挂在这个节点之后,因此打印时第一个值为0。指针传递错误导致头指针无法正确更新
newNode等函数接收的是USER* start(值传递),当start为NULL时,函数内修改start的操作不会影响main函数中的头指针,若直接通过添加功能创建第一个节点会失败。打印函数循环条件错误
print函数中while(value->next != NULL)的条件会导致最后一个节点无法被打印,因为当value指向最后一个节点时,value->next为NULL,循环直接终止。
修复步骤与完整代码
修复后的完整代码
#include <stdio.h> #include <stdlib.h> typedef struct USER{ int number; struct USER *next; }USER; // 尾部添加节点(支持创建第一个节点) int newNode(USER** start){ int num; USER *newUser = (USER*)malloc(sizeof(USER)); if (newUser == NULL ){ perror("Memory allocation failed."); exit(1); } printf("\nGive a new number: "); scanf("%d", &num); newUser->number = num; newUser->next = NULL; if (*start == NULL){ *start = newUser; }else{ USER *value = *start; while(value->next != NULL){ value = value->next; } value->next = newUser; } return 0; } // 指定位置插入节点(增加边界检查) int newNode_position(USER** start){ USER *newUser = (USER*)malloc(sizeof(USER)); if (newUser == NULL ){ perror("Memory allocation failed."); exit(1); } printf("\nGive a new number: "); scanf("%d", &newUser->number); int position; printf("Into which node do you want to place the number: "); scanf("%d", &position); if (*start == NULL) { printf("List is empty, cannot insert at specified position.\n"); free(newUser); return 1; } USER *value = *start; for(int i = 1; i < position - 1; i++){ if (value->next == NULL) { printf("Position out of range.\n"); free(newUser); return 1; } value = value->next; } newUser->next = value->next; value->next = newUser; printf("The following numbers are in the list: \n"); value = *start; while(value != NULL){ printf("%d ", value->number); value = value->next; } printf("\n"); return 0; } // 打印所有节点 void print(USER *start){ USER *value = start; printf("Following numbers are now in the list: \n"); while(value != NULL){ printf("%d ", value->number); value = value->next; } printf("\n"); } // 清空链表并重置头指针 void freeMem(USER** start){ USER *value = NULL; while (*start != NULL){ value = *start; *start = value->next; free(value); } } int main(void){ int choice; USER *start = NULL; printf("This program let's you create a linked list and manage it.\n"); do { printf("\n1) Insert a new node in the end\n"); printf("2) Insert a new node in the middle, to a specified position\n"); printf("3) Clear the list\n"); printf("4) Delete certain node from the list\n"); printf("5) Print the list\n"); printf("0) Quit\n"); printf("Your choice: "); scanf("%d", &choice); switch(choice){ case 1: newNode(&start); break; case 2: newNode_position(&start); break; case 3: freeMem(&start); printf("List cleared.\n"); break; case 5: print(start); break; case 0: freeMem(&start); printf("\nThank you for using the program."); break; default: printf("Unknown choice.\n"); break; } } while(choice != 0); return 0; }
关键修改说明
移除冗余的
allocMem函数
改为直接通过“尾部添加”功能创建第一个节点,避免生成未初始化的空节点,逻辑更简洁合理。使用指针的指针传递头指针
所有需要修改头指针的函数(newNode、newNode_position、freeMem)均改为接收USER** start,确保main函数中的头指针能被正确更新。修复打印循环条件
将while(value->next != NULL)改为while(value != NULL),确保链表中所有节点的值都能被打印。增加边界检查
在newNode_position中添加空链表、位置越界的判断,避免程序崩溃。
内容的提问来源于stack exchange,提问作者cosman
相关产品推荐
相关产品推荐

