C语言链表程序:while循环无法多次输入、showLL函数无输出问题排查
问题修复方案
核心问题分析
- 循环提前终止:main函数中输入整数后执行
return bo;,直接退出main函数,导致只能输入一次就结束程序,无法多次输入。 - 链表头节点未正确更新:
joinLL函数中,头节点head是按值传递的,函数内对head的修改不会影响main函数中的head指针,导致新节点无法正确挂载到链表上,最终链表始终为空。 - 打印逻辑冗余:
showLL函数中每次遍历节点都打印"Done. List is",输出格式混乱。 - 不必要的全局变量:
int a定义为全局变量,完全可以改为main函数内的局部变量,避免全局变量带来的潜在问题。
修复步骤
- 移除循环内的提前返回:删除
if(scanf(...))块中的return bo;,让循环可以继续执行,直到输入非整数才退出。 - 修改joinLL函数的参数传递方式:将
joinLL的参数改为NodeT **head(指针的指针),这样函数内可以直接修改main函数中的头指针,正确挂载新节点。 - 调整showLL的打印逻辑:只在开头打印一次提示,然后依次输出节点数据,最后打印
NULL表示链表结束,优化输出格式。 - 将全局变量a改为局部变量:在main函数内定义
int a;,避免全局变量的使用。 - 处理scanf失败后的输入缓冲区:当输入非整数时,scanf会把无效字符留在输入缓冲区,需要清空缓冲区,避免后续操作受影响。
完整修正代码
#include <stdio.h> #include<stdlib.h> #include<assert.h> #include <stdbool.h> typedef struct node { int data; struct node *next; } NodeT; NodeT *makeNode(int v); void joinLL(NodeT **head, int v); void showLL(NodeT *head); void freeLL(NodeT *head); int main(void){ NodeT *head= NULL; bool bo=true; int a; // 改为局部变量 while (bo){ printf("Enter an integer:"); if (scanf("%d", &a) == 1){ // 明确判断返回值为1(成功读取整数) joinLL(&head, a); } else { printf("Done.\n"); // 清空输入缓冲区的无效字符 while(getchar() != '\n'); break; } } showLL(head); freeLL(head); return 0; } // 创建新节点 NodeT *makeNode(int v) { NodeT *new = malloc(sizeof(NodeT)); assert(new != NULL); new->data = v; new->next = NULL; return new; } // 在链表末尾添加新元素 void joinLL(NodeT **head, int v){ NodeT *insert = makeNode(v); insert->next = NULL; if (*head == NULL){ *head = insert; // 修改main中的头指针 } else { NodeT *temp = *head; while (temp->next != NULL){ temp = temp->next; } temp->next = insert; } } // 打印链表内容 void showLL(NodeT *head) { if (head == NULL) { printf("List is empty.\n"); return; } printf("Done. List is: "); NodeT *p; for (p = head; p != NULL; p = p->next) { printf("%d", p->data); if (p->next != NULL) { printf("-->"); } } printf("-->NULL\n"); // 标记链表结束 } // 释放链表内存 void freeLL(NodeT *head) { NodeT *p, *temp; p = head; while (p != NULL) { temp = p->next; free(p); p = temp; } }
修复说明
- 循环修复:移除
return bo;后,每次输入整数都会继续循环,直到输入非整数才退出。 - 头指针更新:通过传递
&head(头指针的地址)到joinLL,函数内使用*head直接修改main中的头指针,确保新节点能正确添加到链表中。 - 打印优化:先判断链表是否为空,不为空时统一打印开头提示,然后依次输出节点,最后用
-->NULL明确链表结束,输出更清晰。 - 缓冲区清空:输入非整数时,用
while(getchar() != '\n');清空缓冲区,避免无效字符残留导致后续操作异常。
内容的提问来源于stack exchange,提问作者xzha_athena
相关产品推荐
相关产品推荐

