- •Предисловие
- •Основы программирования
- •Понятие алгоритма.
- •Алгоритм Евклида.
- •Задача о поездах и мухе
- •Вместо лирического отступления
- •Этапы подготовки задачи для решения на компьютере
- •Примеры разработки алгоритмов
- •Решение квадратного уравнения.
- •Вычисление интегралов
- •Обработка результатов эксперимента
- •Решение системы линейных алгебраических уравнений
- •Введение в язык программирования Pascal
- •Основные элементы языка
- •Переменные. Стандартные типы.
- •Операции отношения
- •Раздел описаний переменных
- •Выражения. Порядок выполнения операций.
- •Константы
- •Комментарии в программе
- •Операторы
- •2.1.7.1. Оператор присваивания
- •2.1.7.2. Операторы ввода/вывода
- •2.1.7.3. Операторы инкремента и декремента
- •Среда разработки Lazarus
- •Русский язык в консольных приложениях
- •Первая программа
- •Открытие существующего проекта
- •Другие способы создания консольных приложений
- •Типовой пустой проект
- •Операции с целыми числами
- •Вместо лирического отступления 2
- •Стандартные функции с целыми аргументами
- •Операции с вещественными числами (тип real).
- •Форматирование вывода
- •Одновременное использование вещественных и целых чисел.
- •Другие стандартные функции с вещественными аргументами
- •Булевы переменные
- •Условные операторы.
- •2.1.22.1 Оператор if …. then
- •2.1.22.2. Оператор if …then ... else
- •Операторы цикла
- •2.1.23.1. Оператор цикла с предусловием
- •2.1.23.2. Оператор цикла с постусловием
- •2.1.23.3. Оператор цикла с параметром.
- •2.1.23.4. Второй вариант оператора цикла с параметром
- •Оператор выбора case
- •Организация простейшего контроля ввода данных.
- •Вычисление сумм сходящихся рядов
- •Реализация некоторых алгоритмов главы 1.
- •Программа решения задачи о поездах и мухе
- •Программа вычисления определенного интеграла
- •Более сложные элементы языка
- •Общая структура Паскаль – программы
- •Процедуры и функции
- •3.1.1.1 Структура процедуры
- •3.1.1.2. Структура функции
- •3.1.1.3 Глобальные и локальные переменные
- •3.1.1.4 Способы передачи параметров
- •3.1.1.5 Процедуры завершения
- •Еще раз о типах данных
- •Классификация типов данных
- •3.2.1.1 Целый тип
- •3.2.1.2. Интервальный тип
- •3.2.1.3. Перечислимый тип
- •3.2.1.4. Множества
- •3.2.1.5. Логический тип
- •3.2.1.6. Вещественный тип
- •3.2.1.7. Указатели
- •Обработка символьной информации в Паскале
- •Символьные и строковые типы данных.
- •3.3.1.1. Тип Char
- •3.3.1.2. Функции для работы с символами
- •3.3.1.3. Тип String
- •3.3.1.4. Строковые процедуры и функции
- •Массивы
- •Динамические массивы
- •Программа решения системы линейных алгебраических уравнений методом Гаусса
- •3.4.1.1. Вариант 1 – с goto
- •3.4.1.2. Вариант 2 – без goto
- •3.4.1.3. Вариант 3 – наилучшая реализация
- •Модули в Паскале
- •Структура модуля
- •Системные модули
- •3.5.2.1. Модуль CRT
- •Файлы
- •Тип данных – запись
- •Файловые типы
- •Процедуры для работы с файлами
- •3.6.3.1. Общие процедуры для работы с файлами всех типов
- •3.6.3.2. Процедуры для работы с текстовыми файлами
- •3.6.3.3. Процедуры для работы с типизированными файлами
- •3.6.3.4. Процедуры для работы с нетипизированными файлами
- •3.6.3.5. Организация контроля ввода/вывода при работе файлами
- •3.6.3.6. Создание простой базы данных с типизированными файлами.
- •Алгоритмы сортировки
- •Обменная сортировка (метод "пузырька")
- •Сортировка выбором
- •Сортировка вставками
- •Метод быстрой сортировки
- •Алгоритмы поиска
- •Поиск в массивах
- •Вставка и удаление элементов в упорядоченном массиве
- •Динамические структуры данных
- •Представление в памяти компьютера динамических структур.
- •Реализация стека с помощью массивов
- •Указатели
- •Стандартные операции с линейными списками
- •Реализация динамических структур линейными списками
- •4.3.6.1. Реализация стека
- •4.3.6.2. Реализация очереди с помощью линейного списка
- •4.3.6.3. Реализация двоичного дерева с помощью линейного списка
- •Сортировка и поиск с помощью двоичного дерева
- •Три источника и три составные части ООП.
- •Классы и объекты.
- •Обращение к членам класса.
- •Инкапсуляция
- •Спецификаторы доступа.
- •Свойства.
- •Наследование
- •Полиморфизм
- •Раннее связывание.
- •Позднее связывание.
- •Конструкторы и деструкторы.
- •Элементы графического интерфейса
- •Различия между консольными и графическими приложениями
- •Визуальное программирование в среде Lazarus
- •Создание графического приложения
- •Форма и ее основные свойства
- •Компоненты
- •Обработчики событий
- •Простейшие компоненты
- •6.3.5.1. Компонент TLabel
- •6.3.5.2. Кнопки TButton, TBitBtn и TSpeedButton
- •6.3.6.1. Компонент TEdit
- •6.3.6.2. Компонент TLabeledEdit
- •6.3.7.1. Компонент TMaskEdit
- •Специальные компоненты для ввода чисел
- •Тестирование и отладка программы
- •Компоненты отображения и выбора данных
- •6.3.10.1. Компонент TMemo
- •6.3.10.2. Компонент TStringGrid
- •6.3.10.3. Компоненты выбора
- •Компонент TListBox
- •Компонент TComboBox
- •Компоненты выбора – переключатели
- •6.3.10.4. Компоненты отображения структурированных данных
- •Компонент TTreeView
- •Компонент TListView
- •Организация меню. Механизм действий - Actions
- •6.3.11.1. Компонент TMainMenu
- •6.3.11.2. Компонент TToolBar
- •6.3.11.3. Компонент TActionList
- •6.3.11.4. Создание приложений с изменяемыми размерами окон
- •Послесловие
- •Литература
- •Алфавитный указатель
6.3 Визуальное программирование в среде Lazarus
____________________________________________________________________
begin
ShowMessage('Вы успешно авторизовались!');
Close();
end;
end;
procedure TForm1.FormCreate(Sender: TObject); begin
passw:= '1234'; n:= 1;
end;
procedure TForm1.Button1Click(Sender: TObject); begin
avtorization;
end;
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: char);
begin
if Key <> #13 then exit; avtorization;
end; initialization
{$I unit1.lrs}
end.
6.3.6.2. Компонент TLabeledEdit
В палитре компонентов на странице Additional имеется еще одна раз-
новидность однострочного редактора TLabeledEdit. Это фактически тот же
512
Глава 6 Программирование приложений с графическим интерфейсом
____________________________________________________________________
самый однострочный редактор, но с присоединенной к нему надписью. Во многих случаях для удобства пользователя над окнами редактирования необхо-
димо помещать некоторый текст, поясняющий, что за информацию следует вводить пользователю в этом окне. В этих случаях удобнее использовать
TLabeledEdit.
Довольно часто необходимо организовывать ввод числовой информации.
При этом всегда необходимо помнить, что данные вводятся в символьном виде,
то есть в свойстве Text компонентов TEdit и TLabeledEdit содержится строка символов. Если введено число, то для работы с ним как с числом, необ-
ходимо эту строку символов преобразовать во внутреннее представление числа.
Для этого используются функции StrToInt – для преобразования строки в целое число и StrToFloat – для преобразования в вещественное число. С
другой стороны, для того чтобы вывести числовые данные, например результа-
ты вычислений, необходимо выполнить обратное преобразование чисел в их строковое представление. Для этого применяются функции IntToStr – для преобразования целого числа в строку и FloatToStr – для преобразования вещественного числа в строку.
Рассмотрим пример.
Создайте новый проект. Поместите на форму три компонента
TLabeledEdit, четыре кнопки TSpeedButton, одну кнопку TBitBtn и
компонент TStatusBar, расположенную на странице Common Controls,
примерно так, как показано на рис. 6.30.
513
6.3 Визуальное программирование в среде Lazarus
____________________________________________________________________
Рис. 6.30. Форма приложения
Для LabeledEdit1 раскройте свойство EditLabel и установите свойство Caption = "Первое число". Точно так же для LabeledEdit2 ус-
тановите свойство Caption = "Второе число" и для LabeledEdit3 Caption = "Результат".
Для SpeedButton1 установите свойство Caption = " + ". Для
SpeedButton2 свойство Caption = " - ", для SpeedButton3 Caption = " * " и SpeedButton2 свойство Caption = " / ".
Установите для всех кнопок SpeedButton свойства GroupIndex= 1,
свойства AllowAllUp= true.
В обработчик события OnShow для Form1 введите код:
procedure TForm1.FormShow(Sender: TObject);
begin
LabeledEdit1.SetFocus;
end;
В обработчик события OnKeyPress для LabeledEdit1 введите код:
procedure TForm1.LabeledEdit1KeyPress(Sender: TObject;
var Key: char);
514
Глава 6 Программирование приложений с графическим интерфейсом
____________________________________________________________________
begin
if Key = #13 then begin
LabeledEdit2.SetFocus; SpeedButton1.Down:= false; SpeedButton2.Down:= false; SpeedButton3.Down:= false; SpeedButton4.Down:= false; exit;
end;
end;
В обработчик события OnClick для SpeedButton1 введите код:
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
LabeledEdit3.Text:=IntToStr(StrToInt(LabeledEdit1.Text)
+ StrToInt(LabeledEdit2.Text));
StatusBar1.SimpleText:= 'Сложение';
LabeledEdit1.SetFocus;
LabeledEdit1.SelectAll;
end;
В обработчик события OnClick для SpeedButton2 введите код:
procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
LabeledEdit3.Text:=IntToStr(StrToInt(LabeledEdit1.Text)
- StrToInt(LabeledEdit2.Text));
515
6.3 Визуальное программирование в среде Lazarus
____________________________________________________________________
StatusBar1.SimpleText:= 'Вычитание';
LabeledEdit1.SetFocus;
LabeledEdit1.SelectAll;
end;
В обработчик события OnClick для SpeedButton3 введите код:
procedure TForm1.SpeedButton3Click(Sender: TObject);
begin
LabeledEdit3.Text:=IntToStr(StrToInt(LabeledEdit1.Text)
* StrToInt(LabeledEdit2.Text));
StatusBar1.SimpleText:= 'Умножение';
LabeledEdit1.SetFocus;
LabeledEdit1.SelectAll;
end;
В обработчик события OnClick для SpeedButton4 введите код:
procedure TForm1.SpeedButton4Click(Sender: TObject);
begin
LabeledEdit3.Text:=IntToStr(StrToInt(LabeledEdit1.Text)
div StrToInt(LabeledEdit2.Text));
StatusBar1.SimpleText:= 'Деление нацело';
LabeledEdit1.SetFocus;
LabeledEdit1.SelectAll;
end;
Здесь новым для нас является компонент TStatusBar, который позволя-
ет выводить в окне так называемую строку состояния. В этой строке приложе-
516
Глава 6 Программирование приложений с графическим интерфейсом
____________________________________________________________________
ние обычно выводит различную вспомогательную информацию. В нашей про-
грамме будет выводиться информация о последней выполненной операции.
В строке состояния можно определить одну или несколько независимых панелей. Если вы хотите иметь всего одну панель, то установите свойство
SimplePanel = true. В этом случае для вывода текста в строку состояния используйте свойство SimpleText. Если вам необходимо иметь несколько панелей установите свойство SimplePanel = false. Тогда для вывода текста в нужную панель используйте свойство Panels[k], где номер k панели
(нумерация с 0) или подсвойство Items, например:
StatusBar1.Panels[0].Text:= 'Какой либо текст'; StatusBar1.Panels.Items[0].Text:= 'Какой либо текст';
Откомпилируйте и запустите программу. Опробуйте работу кнопок.
В процессе ввода информации пользователи довольно часто допускают ошибки. В большинстве случаев эти ошибки носят случайный и непреднаме-
ренный характер, но могут вызвать сбой или даже аварийное завершение про-
граммы. Поэтому программист должен предусматривать соответствующие ме-
ры защиты своих программ от такого рода ошибок.
В нашем примере мы реализовали действия для целых чисел. При вводе чисел пользователь может, например, ввести недопустимый символ или вместо целого ввести вещественное число. В этой программе никакого контроля при вводе нет. В таких случаях программа, как правило, аварийно завершается. В
2.1.14 и 2.1.25 мы уже касались этого вопроса.
При возникновении какой-либо ошибочной ситуаций (говорят еще исклю-
чительной ситуации) генерируется так называемое исключение. К возникнове-
нию исключений могут привести не только действия пользователя, но и ряд других обстоятельств. Например, обращение к несуществующему файлу, обра-
517
6.3 Визуальное программирование в среде Lazarus
____________________________________________________________________
щение к устройству, которое в этот момент не готово, выход за пределы выде-
ленной динамической области памяти, деление на ноль, переполнение разряд-
ной сетки и пр. Программист обязан и для таких случаев предусмотреть какие-
то действия, чтобы не допустить краха своей программы.
Отвлечемся на некоторое время от изучения компонентов и рассмотрим некоторые способы обнаружения и организации соответствующей реакции программы в случае возникновения каких-либо ошибочных ситуаций.
6.3.7 Обработка исключений. Компонент TMaskEdit. Организация кон-
троля ввода данных
Для обработки стандартных исключений в Lazarus имеются специальные классы. Если в программе не предусмотрена обработка какого-нибудь исклю-
чения, то оно обрабатывается глобальным обработчиком. Он обеспечивает стандартную реакцию на возникшее исключение – выводит предупреждение на экран с кратким описанием причины, вызвавшее исключение, рис. 6.31.
Рис. 6.31. Стандартная реакция на исключение
Здесь указано, что произошла попытка деления на ноль и предлагаются ва-
рианты действий – продолжить выполнение программы или завершить ее.
В большинстве случаев стандартной реакции оказывается недостаточной.
Поясню примером. Предположим, в программе создается временный файл, ко-
торый после завершения программы должен быть удален. Пусть во время рабо-
518
Глава 6 Программирование приложений с графическим интерфейсом
____________________________________________________________________
ты программы с файлом произошла ошибка. Скажем, был прочитан недопусти-
мый символ. Обработка такой ошибки программистом не был предусмотрен.
Тогда последует стандартная реакция, рис. 6.32.
Рис. 6.32. Стандартная реакция на исключение
Пользователь закрывает программу, нажав кнопку Cancel. А временный файл, который должен был быть уничтожен, останется на диске! Существуют очень много программ, которые оставляют после своей работы всякий "мусор"
на диске, если они завершаются аварийно. И это происходит из-за того, что программист не предусмотрел соответствующих действий по очистке мусора в случае возникновения исключительных ситуаций.
В таких случаях гораздо лучше, если программист организует свою собст-
венную обработку исключения, в которой и выполнит очистку мусора. Кроме того, программист знает логику работы своего приложения, знает – где именно произошло исключение и, в большинстве случаев, почему это произошло, по-
этому он может выдать пользователю более развернутое описание причины ошибки, к тому же на русском языке, а также предусмотреть такие действия,
которые могли бы пользователю продолжить работу (если это возможно).
Рассмотрим некоторые классы исключений.
EConvertError – ошибка преобразования типов. Чаще всего происходит при преобразовании строки в число.
EDivByZero – попытка деления целого числа на ноль.
EZeroDivide – попытка деления вещественного числа на ноль.
519
6.3 Визуальное программирование в среде Lazarus
____________________________________________________________________
ERangeError – выход за пределы допустимого диапазона индекса или порядкового типа.
EIntOverflow – переполнение в операциях с целыми числами, т.е. по-
пытка присвоения переменной целого типа значения больше допустимого.
EOverflow – переполнение в операциях с вещественными числами.
EUnderflow – потеря значащих разрядов в операциях с вещественными
числами.
EAccessViolation – попытка обращения к недействительному адресу в памяти. Чаще всего возникает из-за неправильной работы с указателями.
Для обработки исключений используются две конструкции. Первая конст-
рукция имеет вид:
try
< Потенциально "опасные" операторы, при выполнении которых могут возникнуть исключительные ситуации >
except
on класс исключения 1 do < оператор обработки исключения 1 >; on класс исключения 2 do < оператор обработки исключения 2 >;
………………………………………………………………………………………………………………………………
on класс исключения n do < оператор обработки исключения n >;
else
< операторы обработки остальных исключений >
end;
Данная конструкция означает, что после ключевого слова try и до клю-
чевого слова except следуют операторы, при выполнении которых возмож-
но возникновение исключений. После except следуют операторы, которые
520
Глава 6 Программирование приложений с графическим интерфейсом
____________________________________________________________________
образуют секцию обработки исключений. Признаком конца секции служит ключевое слово end. Внутри секции программист указывает классы исключе-
ний (говорят еще типы исключений) после слова on, а затем после ключевого слова do оператор обработки исключения, причем оператор может быть со-
ставным. После необязательного else следуют операторы обработки исклю-
чений, не вошедшие в перечень on. Если программисту нужно только устано-
вить сам факт исключения, независимо от типа, то он может просто записать обработчик исключения после слова except.
Вторая конструкция имеет вид:
try
<Потенциально "опасные" операторы, при выполнении которых могут возникнуть исключительные ситуации >
finally
<операторы, которые должны быть выполнены в любом случае, незави-
симо от того, произошло исключение или нет >
end;
В чем их различие? В конструкции try..except если при выполнении операторов секции try возникло исключение, то управление передается в сек-
цию except, где и происходит обработка исключения. Если же исключения не произошло, то операторы блока except просто пропускаются. В конструкции try..finally операторы будут выполнены независимо от того, произошло исключение или нет.
Рассмотрим пример:
try
num:=StrToInt(Stroka);
except
521
6.3 Визуальное программирование в среде Lazarus
____________________________________________________________________
on EConvertError do
ShowMessage('Ошибка преобразования строки в целое число');
end;
Здесь сообщение будет выведено только в том случае, когда невозможно преобразование строки символов в целое число, то есть когда возникнет ис-
ключение EConvertError.
Конструкции try..except и try..finally могут быть вложены друг в друга на неограниченную глубину. Рассмотрим реализацию примера с файлом.
Procedure Test; var
F: TextFile; number: integer; s: string;
begin
AssignFile(F, 'Data.txt');
Rewrite(F);
s:= '12#4'; |
// В файл намеренно записывается |
|
Writeln(F, s); |
// ошибочная строка символов |
|
Reset(F); |
|
|
try |
// начало секции (блока) try..except |
|
Readln(F, s); |
|
|
try |
// начало секции try..finally |
number:= StrToInt(s);
finally
CloseFile(F); // эти два оператора будут выполнены
DeleteFile('Data.txt'); // в любом случае
522
Глава 6 Программирование приложений с графическим интерфейсом
____________________________________________________________________
end; // конец секции try..finally
except
on EConvertError do
ShowMessage('Ошибка преобразования'); end; // конец секции try..except
end;
Вернемся к примеру, в котором осуществляется ввод двух целых чисел и выполняются четыре арифметических действия (сложение, вычитание, умно-
жение и деление нацело), рис. 6.30. Модифицируем программу, добавив в него обработку исключений. Перепишите обработчики события OnKeyPress для
LabeledEdit1 и событий OnClick кнопок SpeedButton1, SpeedButton2, SpeedButton3 и SpeedButton4 в виде:
procedure TForm1.LabeledEdit1KeyPress(Sender: TObject; var Key: char);
begin
if Key = #13 then begin
try StrToInt(LabeledEdit1.Text);
except
on EConvertError do begin
ShowMessage('Ошибка преобразования! Вероятно, ' +
'Вы ошиблись при вводе числа');
exit;
end;
end;
523
6.3 Визуальное программирование в среде Lazarus
____________________________________________________________________
LabeledEdit2.SetFocus; SpeedButton1.Down:= false; SpeedButton2.Down:= false; SpeedButton3.Down:= false; SpeedButton4.Down:= false; exit;
end;
end;
procedure TForm1.SpeedButton1Click(Sender: TObject); begin
try LabeledEdit3.Text:=IntToStr(StrToInt(LabeledEdit1.Text)
+ StrToInt(LabeledEdit2.Text));
except
on EConvertError do begin
ShowMessage('Ошибка преобразования! Вероятно, ' + 'Вы ошиблись при вводе второго числа');
exit;
end;
end;
StatusBar1.SimpleText:= 'Сложение';
LabeledEdit1.SetFocus;
LabeledEdit1.SelectAll;
end;
procedure TForm1.SpeedButton2Click(Sender: TObject); begin
524
Глава 6 Программирование приложений с графическим интерфейсом
____________________________________________________________________
try LabeledEdit3.Text:=IntToStr(StrToInt(LabeledEdit1.Text)
- StrToInt(LabeledEdit2.Text));
except
on EConvertError do begin
ShowMessage('Ошибка преобразования! Вероятно, ' + 'Вы ошиблись при вводе второго числа');
exit;
end;
end;
StatusBar1.SimpleText:= 'Вычитание';
LabeledEdit1.SetFocus;
LabeledEdit1.SelectAll;
end;
procedure TForm1.SpeedButton3Click(Sender: TObject); begin
try LabeledEdit3.Text:=IntToStr(StrToInt(LabeledEdit1.Text)
* StrToInt(LabeledEdit2.Text));
except
on EConvertError do begin
ShowMessage('Ошибка преобразования! Вероятно, ' +
'Вы ошиблись при вводе второго числа');
exit;
end;
end;
525
6.3 Визуальное программирование в среде Lazarus
____________________________________________________________________
StatusBar1.SimpleText:= 'Умножение';
LabeledEdit1.SetFocus;
LabeledEdit1.SelectAll;
end;
procedure TForm1.SpeedButton4Click(Sender: TObject); begin
try LabeledEdit3.Text:=IntToStr(StrToInt(LabeledEdit1.Text)
div StrToInt(LabeledEdit2.Text));
except
on EConvertError do begin
ShowMessage('Ошибка преобразования! Вероятно, ' + 'Вы ошиблись при вводе второго числа');
exit;
end;
on EDivByZero do begin
ShowMessage('Ошибка! Произошло деление на ноль. Вероятно, ' + 'Вы ошиблись при вводе второго числа');
exit;
end;
end;
StatusBar1.SimpleText:= 'Деление нацело';
LabeledEdit1.SetFocus;
LabeledEdit1.SelectAll;
end;
526
Глава 6 Программирование приложений с графическим интерфейсом
____________________________________________________________________
Теперь при вводе недопустимого символа для целого числа, а также при вводе числа 0 в качестве второго операнда программа перехватывает исключе-
ния и реагирует соответствующим образом.
Имейте в виду, если вы запускаете программу из среды Lazarus, то исклю-
чения будет перехватывать отладчик. Поэтому лучше запускать программу из командной строки или в настройках окружения для отладчика добавьте нужные вам типы исключений в список игнорирования.
Обработку исключений вполне можно применять и в консольных прило-
жениях. Вспомним программу из 2.1.14. Организуем контроль ввода данных,
используя механизм исключений.
program int_operations_control; {$mode objfpc}{$H+}
uses
CRT, FileUtil, SysUtils; var
A, B, C: integer; begin
writeln(UTF8ToConsole('Введите два числа')); readln(A, B);
writeln('A= ', A, ' B= ', B); C:= A + B;
writeln(UTF8ToConsole('Демонстрация сложения, C= '), C); C:= A * B;
writeln(UTF8ToConsole('Демонстрация умножения, C= '), C); try
C:= A div B;
writeln(UTF8ToConsole('Демонстрация деления нацело, C= '),
C);
527
6.3 Визуальное программирование в среде Lazarus
____________________________________________________________________
except
on EDivByZero do
begin
writeln(UTF8ToConsole('Ошибка!! Деление на ноль.')); writeln(UTF8ToConsole('Нажмите любую клавишу'));
readkey;
exit;
end;
end;
C:= A mod B;
writeln(UTF8ToConsole('Остаток от деления, C= '), C);
C:= A - B;
writeln(UTF8ToConsole('Демонстрация вычитания, C= '), C); writeln(UTF8ToConsole('Нажмите любую клавишу'));
readkey;
end.
Сравните эту программу с программой из 2.1.25.
Контроль и обработку ошибок с применением механизма исключений удобнее использовать, когда работа программы уже не зависит от действий пользователя, т.е. все необходимые данные от пользователя уже получены,
программа перешла непосредственно к обработке данных – идут вычисления,
происходит чтение и запись в файлы, обращения к различным внешним уст-
ройствам и т.д. На этапе же ввода данных, когда пользователь в режиме диало-
га вводит какие-то данные с клавиатуры, удобнее использовать другой способ контроля. Поскольку обработка исключений происходит после завершения ввода пользователем, то есть этим происходит только констатация факта, что ошибка пользователем уже совершена. Приходится организовывать повторный ввод, причем с того места, где пользователь ошибся. А это приведет к усложне-
528