Компания ALT Linux
Опубликован: 10.04.2015 | Доступ: свободный | Студентов: 762 / 0 | Длительность: 14:03:00
Специальности: Программист, Преподаватель
Лекция 4:

Подпрограммы

4.5 Решение задач с использованием подпрограмм

В этом разделе мы рассмотрим задачи с несложными алгоритмами, но больше внимания уделим их интерфейсу в среде Lazarus.

ЗАДАЧА 4.5. Создать программу, которая автоматизирует процесс перевода градусной меры угла в радианную и наоборот, в зависимости от выбора пользователя. То есть пользователь должен выбрать, как он будет вводить угол: в радианах или в градусах. Если введёт в радианах, ответ получит в градусах и, соответственно, введёт в градусах — ответ получит в радианах.

С точки зрения математика задача не вызывает сложности:

  • чтобы найти радианную меру какого-нибудь угла по данной градусной мере, нужно помножить число градусов на \pi/180, число минут на \pi/(180 \cdot 60), число секунд на \pi/(180 \cdot 60 \cdot 60) и найденные произведения сложить;
  • чтобы найти градусную меру угла по заданной радианной, нужно помножить число радиан на 180/\pi; если из полученной дроби выделить целую часть, то получим градусы; если из числа, полученного умножением оставшейся дробной части 60, выделить целую часть, получим минуты; секунды вычисляются аналогично из дробной части минут.

Для перевода угла из градусной меры в радианную создадим функцию

function gradus_radian ( gradus, minuta, secunda : byte ) : real;

в которую будем передавать целочисленные значения градусов, минут и секунд. Результат работы функции — вещественное число, величина угла в радианах.

Задачу перевода из радианной меры в градусную решим, создав процедуру

procedure radian_gradus ( radian : real;
		var gradus, minuta, secunda : byte );

у которой один входной параметр — радианная мера угла и три выходных — градусы, минуты и секунды.

Разработаем интерфейс будущей программы в среде Lazarus. Создадим новый проект, установим свойства формы так, как показано в табл. 4.1, и разместим на ней компоненты в соответствии с рис. 4.1.

С компонентами Edit, Label и Button мы уже хорошо знакомы. Компонент RadioButton — это переключатель. Его используют для выбора одного из нескольких взаимоисключающих решений. Обычно на форму помещается, по меньшей мере, два таких компонента. Они могут иметь только два состояния, определяемых свойством Checked. Если у одного из компонентов это свойство истинно (true), то во всех остальных ложно (false). В данной задаче используется два компонента: RadioButton1 и RadioButton2, предоставляя пользователю выбор: включён первый компонент — будет осуществлён перевод из градусной меры в радианную, включен второй — наоборот. Двойной щелчок по компоненту RadioButton1 приведёт к созданию процедуры TForm1.RadioButton1Click обработки события щелчок мыши по кнопке переключателю. В тексте процедуры следует указать команды, которые будут выполняться, если пользователь включил или выключил компонент.

Таблица 4.1. Свойства формы
Свойство Значение Описание свойства
Caption Величина угла Заголовок формы
Height 265 Высота формы
Width 325 Ширина формы
BorderIcons.BiMaximize false Кнопка развёртывания окна недоступна
BorderStyle bdDialog Стиль рамки — диалоговое окно, не изменяет размеры
Position poScreenCenter Окно появится в центре экрана
Настройка формы к задаче 4.5

Рис. 4.1. Настройка формы к задаче 4.5

Нам уже известно, что свойства компонентов могут изменяться как в окне конструирования формы, так и непосредственно в программе. Если дважды щелкнуть по форме, вне размещённых на ней компонентов, то будет создана процедура TForm1.FormCreate обработки события открытия формы. На вкладке События инспектора объектов это событие носит название OnCreate. Процедура OnCreate выполняется в момент создания формы. Все действия, включённые в неё, будут выполнены перед первым выводом формы на экран. Здесь можно задать свойства всех компонентов на момент открытия формы.

Кнопки, расположенные на форме, несут следующую функциональную нагрузку:

  • Button1 запускает процесс перевода в зависимости от установок переключателей;
  • Button3 возвращает внешний вид формы в первоначальное состояние (до ввода и вывода данных);
  • Button2 — завершает процесс выполнения программы.

Текст программы с необходимыми комментариями приведён ниже.

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class (TForm)
Button1 : TButton;
Label1 : TLabel;
RadioButton1 : TRadioButton;
RadioButton2 : TRadioButton;
Edit1 : TEdit;
Button2 : TButton;
Label2 : TLabel;
Edit2 : TEdit;
Edit3 : TEdit;
Label3 : TLabel;
Label4 : TLabel;
Label5 : TLabel;
Edit4 : TEdit;
Button3 : TButton;
procedure Button1Click ( Sender : TObject );
procedure RadioButton1Click ( Sender : TObject );
procedure RadioButton2Click ( Sender : TObject );
procedure FormCreate ( Sender : TObject );
procedure Button2Click ( Sender : TObject );
procedure Button3Click ( Sender : TObject );
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1 : TForm1;
implementation
{$R *.dfm}
//Щелчок по кнопке ВЫЧИСЛИТЬ.
procedure TForm1. Button1Click ( Sender : TObject );
	//Функция перевода данных из градусов в радианы.
	function gradus_radian ( gradus, minuta, secunda : byte ) : real;
	begin
		gradus_radian :=
		gradus * p i /180+minuta * p i /180/60+ secunda * p i /180/60/60;
	end;
	//Процедура перевода из радиан в градусы.
	procedure radian_gradus ( radian : real;
		var gradus, minuta, secunda : byte );
	begin
		gradus := trunc ( radian * 180/ pi );
		minuta := trunc ( ( radian * 180/ pi -gradus ) * 60 );
		secunda := trunc ( ( ( radian * 180/ pi -gradus )*60 - minuta ) * 60 );
	end;
var //Описание переменных.
grad, min, sec : byte; //Градусная мера угла.
rad : real; //Радианная мера угла.
kod_g, kod_m, kod_s, kod_r : integer; //Контроль ввода.
begin
if RadioButton1. Checked then //Если первый переключатель вкл.
begin
	Val ( Edit1. Text, grad, kod_g ); //Ввод градусов.
	Val ( Edit2. Text, min, kod_m ); //Ввод минут.
	Val ( Edit3. Text, sec, kod_s ); //Ввод секунд.
	//Если ошибки при вводе не было, то
	if ( kod_g=0) and (kod_m=0) and ( kod_s=0) then
	begin
	Label2. Visible := true; //сделать видимым компонент Label2
	//и вывести туда результат вычислений.
	//Вызов функции gradus_radian перевода из градусов в радианы.
	Label2. Caption := ’Величина угла  ’ +chr ( 13 )
		+FloatToStrF ( gradus_radian ( grad, min, sec ), ffFixed, 8, 6 )
			+ ’  радиан ’;
	end
	else //Иначе выдать сообщение об ошибке при вводе.
	MessageDlg ( ’Ошибка_при_вводе_данных ! ’, MtWarning, [ mbOk ], 0 );
end;
if RadioButton2. Checked then //Если второй переключатель вкл.
begin
	Val ( Edit4. Text, rad, kod_r ); //Ввод радианной меры угла.
	if ( kod_r=0) then //Если нет ошибок при вводе, то
	begin
	Label2. Visible := true; //сделать видимым компонент Label2
	//и вывести туда результат вычислений.
	//Вызов процедуры перевода из радиан в градусы.
	radian_gradus ( rad, grad, min, sec );
	Label2. Caption := ’Величина_угла ’ +chr ( 1 3 )
		+IntToStr ( grad)+ ’ _г_ ’+IntToStr ( min )
			+ ’  м  ’+IntToStr ( sec )+ ’  с ’;
	end
	else //Иначе выдать сообщение об ошибке при вводе.
	MessageDlg ( ’Ошибка при вводе данных ! ’, MtWarning, [ mbOk ], 0 );
end;
end;
//Щелчок по кнопке ВЫХОД.
procedure TForm1. Button2Click ( Sender : TObject );
begin
	close;
end;
//Щелчок по кнопке ОЧИСТИТЬ.
procedure TForm1. Button3Click ( Sender : TObject );
begin
	//Установка свойств компонентов в первоначальное состояние.
	Edit1. Text := ’ 00 ’;
	Edit2. Text := ’ 00 ’;
	Edit3. Text := ’ 00 ’;
	Edit4. Text := ’ 00.000 ’;
	Label1. Caption := ’Введите_значение ’;
	Label1. Font. Size := 10;
	Label3. Caption := ’Градусы ’;
	Label4. Caption := ’Минуты ’;
	Label5. Caption := ’Секунды ’;
	Button1. Caption := ’ВЫЧИСЛИТЬ ’;
	Button2. Caption := ’ВЫХОД ’;
	Button3. Caption := ’ОЧИСТИТЬ ’;
	Edit4. Enabled := false;
	Label2. Visible := false;
	RadioButton1. Checked := true;
	RadioButton2. Checked := false;
end;
//Обработка события открытие формы.
procedure TForm1. FormCreate ( Sender : TObject );
begin
	//Установка свойств компонентов.
	Edit1. Text := ’ 00 ’;
	Edit2. Text := ’ 00 ’;
	Edit3. Text := ’ 00 ’;
	Edit4. Text := ’ 00.000 ’;
	Label1. Caption := ’Введите_значение ’;
	Label1. Font. Size := 10;
	Label3. Caption := ’Градусы ’;
	Label4. Caption := ’Минуты ’;
	Label5. Caption := ’Секунды ’;
	Button1. Caption := ’ВЫЧИСЛИТЬ ’;
	Button2. Caption := ’ВЫХОД ’;
	Button3. Caption := ’ОЧИСТИТЬ ’;
	Edit4. Enabled := false;
	Label2. Visible := false;
	RadioButton1. Checked := true;
	RadioButton2. Checked := false;
end;
//Обработка события щелчок по переключателю RadioButton1.
procedure TForm1. RadioButton1Click ( Sender : TObject );
begin
	if RadioButton1. Checked then
	begin
		Edit1. Enabled := true;
		Edit2. Enabled := true;
		Edit3. Enabled := true;
		Label5. Enabled := true;
		Label3. Enabled := true;
		Label4. Enabled := true;
		Edit4. Enabled := false;
	end;
end;
//Обработка события щелчок по переключателю RadioButton2.
procedure TForm1. RadioButton2Click ( Sender : TObject );
	begin
	if RadioButton2. Checked then
	begin
		Edit4. Enabled := true;
		Button1. Enabled := true;
		Edit1. Enabled := false;
		Edit2. Enabled := false;
		Edit3. Enabled := false;
		Label3. Enabled := false;
		Label4. Enabled := false;
		Label5. Enabled := false;
	end;
end; end.

Результаты работы программы представлены на рис. 4.2 и рис. 4.3.

Перевод значений из градусной меры в радианную

Рис. 4.2. Перевод значений из градусной меры в радианную
Перевод значений из радианной меры в градусную

Рис. 4.3. Перевод значений из радианной меры в градусную
Юрий Шутиков
Юрий Шутиков

По первому тесту выполнил дважды задания. Результат получается правильный (проверял калькулятором). Пишет, что "Задание не проверено" и предлагает повторить. 
 

Евгений Силуков
Евгений Силуков

Еще в декабре выполнил тест №1, а его все так и не проверили.