Pascal链表supression()过程删除学生后查询异常问题排查
Pascal学生管理程序删除功能异常排查求助
我编写的Pascal学生管理程序存在问题:插入多名学生后调用supression()执行删除操作,后续查询已删除学生时程序出现异常。推测问题出在supression()过程中,以下是相关代码,请协助排查:
类型声明代码
Program liste_des_etudiants; Type date = Record jour,mois,anee : Integer; End; ptr_etu = ^etudiant; etudiant = Record matricule : String; nom,prenom,adress : String; date_n : date; suiv : ptr_etu; End; ptr_mod = ^module; module = Record code,libelle : String; credit,coeff : Integer; suiv : ptr_mod; End; ptr_note = ^note; note = Record matricule : String; code : String; note : Integer; suiv : ptr_note; End; Var choix : String; liste_etudiant : ptr_etu ; liste_note : ptr_note; liste_module : ptr_mod;
(注:原代码中字符串类型的双引号写法错误,Pascal中字符串类型应使用String而非"String",已修正)
supression过程代码
Procedure supression(Var etu:ptr_etu;module:ptr_mod;note:ptr_note ); var choix,matr,code : String; current,previous,Next: ptr_etu; current_note,previous_note :ptr_note; previous_code,current_code: ptr_mod; begin Repeat Repeat Writeln('pour supression un etudiant tapez 1'); Writeln('pour supression un note tapez 2'); Writeln('pour supression un module tapez 3'); Writeln('pour sortir tapez e '); Readln(choix); Until ((choix='1') Or (choix='2') Or (choix='3') Or (choix='e') Or (choix='E')); If (choix='1') Then Begin // 推测问题在此处 current := etu ; Writeln('donner son matricule') ; Readln(matr); // 处理要删除的是头节点的情况 While((etu<>Nil) And(etu^.matricule=matr))Do etu:= etu^.suiv; // 处理中间节点 While ((current<>Nil) and (current^.suiv<>nil)) Do Begin next:=etu^.suiv; if (next^.matricule=matr) then begin current^.suiv:=next^.suiv; end Else current:=current^.suiv; end; if (current =nil) then writeln('l ''''etudiant n''''est pas trouvee'); Until ((choix='e') Or(choix='E')); end;
主程序代码
Begin Repeat Repeat Writeln('tapez:'); Writeln('1):pour insertion'); Writeln('2):pour modification'); Writeln('3):pour supression'); Writeln('4):pour recherche'); Writeln('(e)pour sortir'); Readln(choix); Until ((choix='1') Or (choix='2') Or (choix='3') Or (choix='4') Or (choix='e')); If (choix='1') Then insertion(liste_etudiant, liste_module,liste_note) Else If (choix='2') Then modification(liste_etudiant, liste_module,liste_note) Else If (choix='3') Then supression(liste_etudiant,liste_module,liste_note) Else if (choix='4') Then recherche(liste_etudiant, liste_module,liste_note) Until ((choix='e') Or (choix='E')); End.
问题分析与修正
原代码中的核心错误
- 中间节点处理逻辑混乱:第二个
While循环中,next:=etu^.suiv完全错误,应获取当前节点current的下一个节点而非头节点的下一个节点;且未正确跟踪前一个节点,导致链表关联断裂。 - current初始化错误:处理完头节点后,
current未重新初始化为更新后的etu,仍使用旧的头节点引用,导致遍历无效。 - 未处理尾节点删除:仅处理头节点和中间节点,遗漏最后一个节点的删除场景。
- 字符串转义错误:提示信息的单引号转义不符合Pascal规范,正确写法应为两个单引号转义一个。
- 变量拼写错误:如
prvious、privous_note等拼写错误,易引发后续维护问题。
修正后的supression过程代码
Procedure supression(Var etu:ptr_etu;module:ptr_mod;note:ptr_note ); var choix,matr,code : String; current,previous: ptr_etu; current_note,previous_note :ptr_note; previous_code,current_code: ptr_mod; found: Boolean; begin Repeat Repeat Writeln('pour supression un etudiant tapez 1'); Writeln('pour supression un note tapez 2'); Writeln('pour supression un module tapez 3'); Writeln('pour sortir tapez e '); Readln(choix); Until ((choix='1') Or (choix='2') Or (choix='3') Or (choix='e') Or (choix='E')); If (choix='1') Then Begin found := False; Writeln('donner son matricule') ; Readln(matr); // 处理头节点:删除所有匹配的头节点 While (etu <> Nil) And (etu^.matricule = matr) Do Begin current := etu; etu := etu^.suiv; Dispose(current); // 释放内存,避免内存泄漏 found := True; End; // 处理中间和尾节点 current := etu; previous := Nil; While (current <> Nil) Do Begin If current^.matricule = matr Then Begin previous^.suiv := current^.suiv; Dispose(current); found := True; current := previous^.suiv; // 继续遍历下一个节点 End Else Begin previous := current; current := current^.suiv; End; End; If Not found Then writeln('l''étudiant n''est pas trouvé'); End; Until ((choix='e') Or(choix='E')); end;
修正说明
- 新增
found标记,明确判断是否找到并删除目标学生。 - 处理头节点时释放被删除节点内存,避免内存泄漏。
- 遍历中间和尾节点时,用
previous跟踪前一个节点,确保链表连接正常。 - 修复字符串转义错误,提示信息更规范。
- 删除无用变量,简化逻辑结构。
内容的提问来源于stack exchange,提问作者hoaifa
相关产品推荐
相关产品推荐

