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

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.

问题分析与修正

原代码中的核心错误

  1. 中间节点处理逻辑混乱:第二个While循环中,next:=etu^.suiv完全错误,应获取当前节点current的下一个节点而非头节点的下一个节点;且未正确跟踪前一个节点,导致链表关联断裂。
  2. current初始化错误:处理完头节点后,current未重新初始化为更新后的etu,仍使用旧的头节点引用,导致遍历无效。
  3. 未处理尾节点删除:仅处理头节点和中间节点,遗漏最后一个节点的删除场景。
  4. 字符串转义错误:提示信息的单引号转义不符合Pascal规范,正确写法应为两个单引号转义一个。
  5. 变量拼写错误:如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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 22:01:19