На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! Правила ЧаВо (FAQ) разделов Паскаля
В этом разделе разрешено создавать только темы, в которых описано РЕШЕНИЕ какой-либо общей проблемы, или описание какого-либо аспекта языка Паскаль.
Обсуждение уже созданных тем разрешено, но только конструктивное, например указание на ошибку или уточнение имеющегося текста.

Также читать Требования к оформлению статей
Модераторы: volvo877, Romtek
  
> Обработка исключительных ситуаций, в Turbo Pascal
    Обработка исключительных ситуаций
    Модуль с примером из книги Фаронова В.В.

    Решает проблемы ошибки деления на ноль, критических ошибок ввода/вывода.

    Пример использования
    ExpandedWrap disabled
      {+-------------------------------------------------------+
       | Программа иллюстрирует механизм выхода из процедуры   |
       |   завершения в нужную точку программы.В программе     |
       | осуществляется ввод произвольного целого числа, затем |
       |   вычисляется корень квадратный из него и находится   |
       | обратная ему величина.Для завершения работы программы |
       |             следует ввести единицу.                   |
       |+------------------------------------------------------+}
      Uses F_Jump;
      var
        OldExit: Pointer;  {Старое значение переменной ExitProc}
        Jump   : JumpRec;  {Сохранение точки выхода}
        rr      : Real;     {Вспомогательная переменная}
      label
        Loop;
      Procedure MyExit; Far;
        {Эта процедура обрабатывает исключительную ситуацию}
      begin
        LongJump(Jump)
      end;  {MyExit}
      begin
        OldExit := ExitProc;
        repeat
      Loop:                   {Точка повторения ввода}
          if ErrorAddr <> NIL then
            begin
              Write('Повторите ввод числа: ');
              ErrorAddr := NIL;
              ExitCode := 0
            end
          else
            Write('Введите число: ');
          ExitProc := @MyExit;        {Адрес процедуры выхода}
          SetJump(Jump);              {Контролируем ввод данных}
          if ErrorAddr <> NIL then
            begin
              WriteLn('Ошибка при вводе вещественного числа');
              Goto Loop
            end
          else
            ReadLn(rr);
          SetJump(Jump);             {Контролируем извлечение корня}
          if ErrorAddr <> NIL then
            begin
              WriteLn('Ошибка при извлечении корня');
              Goto Loop
            end
          else
            rr := sqrt(rr);
          SetJump(Jump);              {Контролируем деление}
          if ErrorAddr <> NIL then
            begin
              WriteLn('Ошибка при делении чисел');
              Goto Loop
            end
          else
            rr := 1/rr;
          WriteLn(r:20:10)
        until rr = 1;
        ExitProc := OldExit       {Нормальный выход}
      end.

    Прикреплённый файлПрикреплённый файлF_JUMP.zip (1.99 Кбайт, скачиваний: 229)
      Цитата SkyStar @
      В Pascal нельзя никак отлавливать исключения.
      Никогда не говори - никогда :D
      Можно создать некий аналог try..except, несколько расширив стандартную возможность перехвата исключений - ExitProc:
      ExpandedWrap disabled
        unit Except;
         
        interface
        type
          Try = record
            _sp, _bp: Word;
            _farptr: Pointer;
          end;
         
        procedure SetExcept(var dest: Try); inline (
        $5f/$07/$26/$89/$25/$26/$89/$6d/$02/
        $e8/$00/$00/$58/$05/$0c/$00/$26/$89/
        $45/$04/$26/$8c/$4d/$06);
         
        procedure ProceedExcept(var dest: Try); inline (
        $5f/$07/$26/$8b/$25/$26/$8b/$6d/$02/
        $26/$ff/$6d/$04);
         
        implementation
         
        end.

      а это пример:
      ExpandedWrap disabled
        uses dos, crt, except;
         
        var
          OldExit: Pointer;
          exc    : Try;
          r      : Real;
        label
          l;
         
        procedure NewExit; far;
        begin
          ExitProc := @NewExit;
          ProceedExcept(exc);
        end;
         
        begin
          OldExit := ExitProc;
          ExitProc := @NewExit;
          repeat
          l:
              Writeln;
              Write('Enter number: ');
              SetExcept(exc);
              Readln(r);
              ErrorAddr := NIL;
              SetExcept(exc);
              if ErrorAddr <> NIL then
                Goto l;
              Writeln('100/',r,'= ',100.0/r);
          until (r=1);
          ExitProc := OldExit;
        end.

      Данный примерчик довольно трудно уронить, он вполне спокойно обруливает неверный ввод числа, а так же деление на ноль.
      Но модуль except не идеален, его нужно немного дополнить, что бы иметь возможность восстанавливать программу даже в особо тяжелых случаях, когда важны значения всех регистров. Но для примера сойдет :)

      Это сообщение было перенесено сюда или объединено из темы "как отлаливать исключение в турбо паскале 7.0"
      1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
      0 пользователей:


      Рейтинг@Mail.ru
      [ Script Execution time: 0,0846 ]   [ 15 queries used ]   [ Generated: 16.07.19, 10:14 GMT ]