
- •Дважды кликните по Button1 на форме.
- •procedure TForm1.Button1Click(Sender:TObject);
- •var a, b, c : real;
- •begin
- •a := StrToFloat(Edit1.Text);
- •b := StrToFloat(Edit2.Text);
- •Edit3.Text := FloatToStr(c);
- •Дважды кликните по Button2 на форме.
- •procedure TForm1.Button2Click(Sender:TObject);
- •var a, b, c : real;
- •begin
- •a := StrToFloat(Edit1.Text);
- •b := StrToFloat(Edit2.Text);
- •Edit3.Text := FloatToStr(c);
- •Дважды кликните по Button3 на форме.
- •procedure TForm1.Button3Click(Sender:TObject);
- •var a, b, c : real;
- •begin
- •a := StrToFloat(Edit1.Text);
- •b := StrToFloat(Edit2.Text);
- •Edit3.Text := FloatToStr(c);
- •Дважды кликните по Button4 на форме.
- •procedure TForm1.Button4Click(Sender:TObject);
- •var a, b, c : real;
- •begin
- •a := StrToFloat(Edit1.Text);
- •b := StrToFloat(Edit2.Text);
- •Edit3.Text := FloatToStr(c);
- •Дважды кликните по Button5 на форме.
- •var a, b, c : real;
- •begin
- •a := StrToFloat(Edit1.Text);
- •b := StrToFloat(Edit2.Text);
- •c:=Power(a,b);
- •Edit3.Text := FloatToStr(c);
- •procedure TForm1.Button1Click(Sender:TObject);
- •begin
- •{Очистить содержимое Memo1}
- •Memo1.Clear;
- •Memo1.Lines.Add (Edit1.Text);
- •Memo1.Lines.Add (ComboBox1.Text);
- •procedure TForm1.Button3Click(Sender:TObject);
- •begin
- •{Очистить содержимое компонента Memo1}
- •Memo1.Clear;
- •procedure TForm1.Button4Click(Sender:TObject);
- •begin
- •{Закрыть форму}
- •Close;
- •begin
- •If RadioGroup1.ItemIndex=0
- •Then Form1.Color:=clSilver;
- •If RadioGroup1.ItemIndex=1
- •Then Form1.Color:=clAqua;
- •If RadioGroup1.ItemIndex=2
- •Then Form1.Color:=clYellow;
- •If RadioGroup1.ItemIndex=3
- •Then Form1.Color:=clRed;
- •begin
- •RadioGroup1.ItemIndex:=ScrollBar1.Position;
- •procedure TForm1.Button2Click(Sender:TObject);
- •begin
- •if CheckBox1.State=cbChecked
- •then Memo1.Font.Color:=clPurple
- •else Memo1.Font.Color:=clBlack;
- •if CheckBox2.State=cbChecked
- •then Memo1.Font.Style:=[fsBold]
- •else Memo1.Font.Style:=[];
- •if RadioButton1.Checked
- •then Memo1.Color:=clWhite;
- •1. Пусть даны три числа. Написать программу, которая определяла бы вид треугольника (равносторонний, равнобедренный, разносторонний, прямоугольный, тупоугольный, остроугольный), если данные числа могут быть длинами сторон треугольника.
- •Подписано к изданию 23.04.2013.
Edit2.Clear; Exit end;
case k of
1:begin res := pi*exp(2*ln(r)); s:='Площадь круга = '; end;
2:begin res := 2*pi*r; s:='Длина окружности = '; end;
3:begin res:=(4*pi*(exp(3*ln(r))))/3; s:='Объем шара=';end; end;
Label4.Caption := s + FloatToStrF(res,ffFixed,6,2);
end;
Для быстрого выбора свойств компонент при написании текста программы после имени компонента и точки нажимайте Ctrl+пробел для вывода полного перечня свойств компонента. После выбора нужного свойства достаточно нажать Enter и свойство автоматически будет добавлено в текст программы.
Решение задач по теме «Ветвления в программах»
В данном пункте особое внимание уделено защите программ от неправильно введенной входной информации и программному ограничению диапазона вводимой информации.
1. Пусть даны три числа. Написать программу, которая определяла бы вид треугольника (равносторонний, равнобедренный, разносторонний, прямоугольный, тупоугольный, остроугольный), если данные числа могут быть длинами сторон треугольника.
В приложении программно поддержана навигация по полям ввода с помощью клавиатуры.
Решение поставленной задачи оформлено в виде отдельной пользовательской процедуры.
Для быстрой идентификации компонентов одного класса удобно назначить им нестандартные имена, связанные со смыслом их использования в приложении.
113

Рис.2.2.4. Вид окна приложения для решения задачи № 1.
Изменение названия компонента Edit1:
•Name Stor_aEdit
Изменение названия компонента Edit2:
•Name Stor_bEdit
Изменение названия компонента Edit3:
•Name Stor_cEdit
Изменение названия компонента Button1:
•Name OtvButton
Изменение названия компонента Label8:
•Name OtvetLabel
Опишем глобальные переменные St_a, St_b, St_c вещественного типа и объявим в классе формы новую пользовательскую процедуру Res().
private
114
St_a, St_b, St_c : Double; procedure Res();
public
Составим обработчик события OnKeyPress (нажата клавиша) для поля ввода длины первой стороны Stor_aEdit.
procedure TForm1.Stor_aEditKeyPress (Sender: TObject; var Key: char);
var
tmpSt_a : double; // временное поле для ввода числа str : string; // введенная последовательность символов flag : boolean; // флаг отсутствия ошибки при вводе i : integer; // счетчик символов
begin
{если нажата клавиша Enter, тогда} if (key = #13) then
begin
{если поле ввода не пусто, то} if (Stor_aEdit.Text <> '') then begin
{запомнить в str введенные символы} str := Stor_aEdit.Text;
{флаг отсутствия ошибки поднять} flag := true;
{просмотреть по одному все введенные символы} {Length(str) – количество символов в строке str} for i := 1 to Length(str) do
{если i-й символ строки не цифра, запятая и минус, то} if not(str[i] in ['0'..'9',',','-']) then
begin
{найдена ошибка – процедуру прервать} flag := false; break;
end;
115
{если в ходе проверки обнаружена ошибка, то} if (flag = false) then
ShowMessage('Допустимы только числовые выражения') else
{если ошибки нет, то преобразовать текст в число} begin
tmpSt_a := StrToFloat(Stor_aEdit.Text);
{если число не положительное, тогда}
If (tmpSt_a <= 0) then begin
ShowMessage('Сторона не может быть отрицательной или нулевой')
end
{если число положительное, то определить значение St_a} else
begin
St_a := tmpSt_a;
{установить фокус на следующее поле для ввода}
Stor_bEdit.SetFocus(); end;
end;
end;
end;
end;
Обработчики нажатия клавиш для полей ввода второго и третьего числа - Stor_bEdit и Stor_cEdit аналогичны приведенному выше коду. После ввода длины стороны b фокус ввода устанавливается на поле Stor_cEdit: Stor_cEdit.SetFocus(); а после ввода длины стороны c – на кнопку OtvButton: OtvButton.SetFocus();
Составим обработчик события OnClick по командной кнопке OtvButton.
Обратите внимание на технику запуска нужных процедур из данной процедуры.
116
procedure TForm1.OtvButtonClick(Sender: TObject); var
ch : char; // один символ begin
ch := #13; // восстановление символа Enter по его коду - 13 {вызов процедур обработки нажатия клавиши в полях ввода} {корректный ввод исходных данных}
Stor_aEditKeyPress (Sender,ch);
Stor_bEditKeyPress (Sender,ch);
Stor_cEditKeyPress (Sender,ch);
{вызов пользовательской процедуры Res для решения задачи и вывода ответа}
Res();
end;
При составлении программ удобнее разбивать решение на небольшие фрагменты – пользовательские процедуры, в каждой из которых оформлено решение некоторой подзадачи, чем писать длинные тексты в одном обработчике.
Тексты пользовательских процедур набираются вручную вместе с заголовком и телом процедуры.
procedure TForm1.Res(); var
cosA,cosB,cosC : double; // косинусы углов треугольника begin
{проверка существования треугольника} {если неравенство треугольника не выполняется, тогда пре-
рвать процедуру с выводом соответствующего сообщения} if (St_a+St_b<=St_c) or (St_a+St_c<=St_b) or (St_b+St_c<=St_a)
then begin
117
ShowMessage('Числа не могут быть длинами сторон треугольника'); exit;
end else
{проверка существования треугольника прошла успешно} {проверка того, что треугольник - равносторонний}
if (St_a = St_b) and (St_a = St_c) and (St_c = St_b) then
begin
OtvetLabel.Caption := 'Треугольник равносторонний'; exit;
end else begin
{вычисление косинусов углов}
cosA := (St_b*St_b + St_c*St_c - St_a*St_a) / (2*St_b*St_c); cosB := (St_a*St_a + St_c*St_c - St_b*St_b) / (2*St_a*St_c); cosC := (St_b*St_b + St_a*St_a - St_c*St_c) / (2*St_b*St_a);
{проверка того, что треугольник – равнобедренный} if (St_a = St_b) or (St_a = St_c) or (St_c = St_b) then
begin
{если есть прямой угол, тогда}
if (cosA = 0) or (cosB = 0) or (cosC = 0) then
begin
OtvetLabel.Caption := 'Треугольник равнобедренный и прямоугольный'; exit;
end else
{если есть тупой угол, тогда}
if (cosA < 0) or (cosB < 0) or (cosC < 0) then
begin
118
OtvetLabel.Caption := 'Треугольник равнобедренный и тупоугольный'; exit;
end else begin
{иначе все углы треугольника - острые}
OtvetLabel.Caption := 'Треугольник равнобедренный и остроугольный'; exit;
end; end
else
{иначе треугольник – разносторонний} {если есть тупой угол, тогда}
if (cosA < 0) or (cosB < 0) or (cosC < 0) then
begin
OtvetLabel.Caption := 'Треугольник разносторонний и тупоугольный'; exit;
end else
{если есть прямой угол, тогда}
if (cosA = 0) or (cosB = 0) or (cosC = 0) then
begin
OtvetLabel.Caption := 'Треугольник разносторонний и прямоугольный'; exit;
end else
{иначе все углы треугольника - острые} begin
OtvetLabel.Caption := 'Треугольник разносторонний и остроугольный'; exit;
end end;
119

end;
2. Введите три числа. Если они могут быть длинами сторон равнобедренного треугольника, то вычислите длины его высот. Выведите основание и длины высот в порядке убывания.
Рис.2.2.5. Вид окна приложения для решения задачи № 2.
procedure TForm1. BitBtn1Click (Sender: TObject); var a, b, c : real; // длины сторон
// площадь, высоты, полупериметр, меньшее число из a и ha
S, ha, hc, p, z : real; res : string; // ответ
begin
// ввод исходных данных
a := StrToFloat(Edit1.Text);
b := StrToFloat(Edit2.Text);
c := StrToFloat(Edit3.Text);
// проверка существования треугольника
120
if (a <= 0) or (b <= 0) or (c <= 0) then if (a+b<=c) or (a+c<=b) or (b+c<=a) then
begin
ShowMessage('Числа не могут быть длинами сторон треугольника'); Exit
end else
//проверка того, что треугольник - равнобедренный if (a<>b) and (a<>c) and (b<>c)
then begin
ShowMessage('Треугольник не равнобедренный!'); Exit
end else begin
//перестановка a, b, c так, что а - основание, b=c
if a=b |
|
|
then begin |
a := c; c := b |
end; |
if a=c |
|
|
then begin |
a := b; b :=c |
end; |
//вычисление площади p := (a + b + c) / 2;
S := sqrt(p*(p-a)*(p-b)*(p-c));
//вычисление высот
ha := 2*S/a; hc := 2*S/c;
//получение в z меньшего из a и ha z:=a;
if ha<z
then begin p := z; z := ha; ha := p end;
//формирование ответа
121
res:='Высоты и основание в порядке возрастания:'+ chr(13); res:=res+'******************************************'+ chr(13);
//сравнение hc и z – меньшее из a и ha if hc<z
then begin
res:=res+FloatToStrF(hc,ffFixed,4,2)+chr(13);
res:=res+FloatToStrF(hc,ffFixed,4,2)+chr(13);
res:=res+FloatToStrF(z,ffFixed,4,2)+chr(13);
res:=res+FloatToStrF(ha,ffFixed,4,2)+chr(13); end
else
if hc<ha then begin
res:=res+FloatToStrF(z,ffFixed,4,2)+chr(13);
res:=res+FloatToStrF(hc,ffFixed,4,2)+chr(13);
res:=res+FloatToStrF(hc,ffFixed,4,2)+chr(13);
res:=res+FloatToStrF(ha,ffFixed,4,2)+chr(13); end
else begin
res:=res+FloatToStrF(z,ffFixed,4,2)+chr(13);
res:=res+FloatToStrF(ha,ffFixed,4,2)+chr(13);
res:=res+FloatToStrF(hc,ffFixed,4,2)+chr(13);
res:=res+FloatToStrF(hc,ffFixed,4,2)+chr(13);
end;
//вывод ответа
Label4.Caption:=res;
end;
end;
122

3. Пусть даны координаты вершин четырехугольника. Составьте программу, которая определяла бы, является ли этот четырехугольник прямоугольником.
Рис.2.2.6. Вид окна приложения для решения задачи № 3.
procedure TForm1.Button1Click(Sender: TObject);
// длины сторон и диагонали
var d1, d2, d3, d4, d5, d6, diag1, diag2 : real; res : string; // отрицательный результат
begin d1:=Sqrt(Sqr(strtofloat(edit3.Text)-strtofloat(edit1.Text))+
Sqr(strtofloat(edit4.Text)-strtofloat(edit2.Text))); //AB d2:=Sqrt(Sqr(strtofloat(edit7.Text)-strtofloat(edit3.Text))+
Sqr(strtofloat(edit8.Text)-strtofloat(edit4.Text))); //BC d3:=Sqrt(Sqr(strtofloat(edit5.Text)-strtofloat(edit7.Text))+
Sqr(strtofloat(edit6.Text)-strtofloat(edit8.Text))); //CD d4:=Sqrt(Sqr(strtofloat(edit5.Text)-strtofloat(edit1.Text))+
123
Sqr(strtofloat(edit6.Text)-strtofloat(edit2.Text))); //AD d5:=Sqrt(Sqr(strtofloat(edit7.Text)-strtofloat(edit1.Text))+
Sqr(strtofloat(edit8.Text)-strtofloat(edit2.Text))); //AC d6:=Sqrt(Sqr(strtofloat(edit5.Text)-strtofloat(edit3.Text))+
Sqr(strtofloat(edit6.Text)-strtofloat(edit4.Text))); //BD //поиск диагоналей
If d5<(d1+d2) Then if d5<(d3+d4) then diag1:=d5; If d6<(d1+d4) Then If d6<(d2+d3) then diag2:=d6;
//проверка равенства диагоналей res:= 'заданый четырёхугольник ' + 'не является прямоугольником'; If diag1<>diag2
Then label13.Caption := res Else
begin
//проверка равенства противоположных сторон
If d1<>d3
Then label13.Caption:= res Else begin
If d2<>d4 Then label13.Caption:= res
Else label13.Caption:='заданый четырёхугольник '+ ' является прямоугольником'
end;
end;
end;
4. В соревнованиях по фигурному катанию оценки выставляют несколько судей. При выведении единой оценки за выступление одного спортсмена из всей совокупности оценок удаляется наиболее высокая и наиболее низкая, и для оставшихся оценок вычисляется среднее арифметическое. Если несколько судей выставили наиболее низкую или наиболее высокую оценку, то из совокупности оценок
124

удаляется одна такая оценка. Напишите программу для вычисления оценки спортсмена.
Рис.2.2.7 Вид окна приложения для решения задачи № 4
Опишем глобальные переменные ниже описания формы.
Обратите внимание на способ указания стартовых значений при описании переменных!
var
Form1: TForm1;
max : Integer; // максимальная оценка min : Integer; // минимальная оценка summ : Integer = 0; // сумма всех оценок
digitNumber : Integer = 0; // количество оценок implementation
Клик по кнопке Ввести добавляет новую оценку в формируемый список оценок (рис. 2.2.7). При этом новая оценка сравнивается с текущими значениями минимальной и максимальной оценок. Если новая оценка оказывается меньше текущего минимума, то происходит замена значения перемен-
125
ной min на новую оценку. Если новая оценка оказывается больше текущего максимума, то происходит соответствующая замена значения переменной max. Новая оценка также добавляется в общую сумму баллов.
procedure TForm1.Button1Click(Sender: TObject); var curDigit : Integer; // новая оценка
begin
digitNumber := digitNumber + 1; curDigit:= StrToInt(Edit1.Text); Edit1.Text := '';
//инициализация переменных max и min
If digitNumber = 1 then begin
max:= curDigit; min:= curDigit;
summ:= summ + curDigit; end
else
//сравнивание новой оценки со текущим значением max и min begin
if max <= curDigit then |
max := curDigit; |
if curDigit <= min then |
min := curDigit; |
// добавление новой оценки в сумму summ := summ + curDigit; end;
// отображение новой оценки в списке оценок
Label3.Caption:= Label3.Caption + ' ' + IntToStr(curDigit) end;
При клике по кнопке Рассчитать вычисляется итоговая оценка. При этом кнопка Ввести становится недоступной.
procedure TForm1.Button2Click(Sender: TObject);
126
var estim : Real; // итоговая оценка спортсмена begin
{ если оценки есть и их не более двух, то итоговой оценкой будет их среднее арифметическое }
if ((digitNumber <= 2) and (digitNumber <> 0)) then estim := summ/digitNumber
{если количество оценок больше двух, тогда используется общий критерий вывода итоговой оценки из условия задачи} else
estim := (summ - (max + min)) / (digitNumber - 2);
// вывод ответа
Label2.Caption:= 'Итоговая оценка: ' + FloatToStr(estim); Button2.Enabled:=false;
end;
Следующий параграф посвящен составлению программ с циклами. В Паскале реализовано три разновидности циклов: цикл с параметром (по возрастанию и убыванию), цикл типа «ПОКА», цикл типа «ДО».
Чем лучше оформлено решение задачи в приложении, тем более вероятно, что в программе использованы ветвления и циклы. Понимание логических основ алгоритмических конструкцией и знание синтаксиса их программной реализации чрезвычайно важно при формировании умения быстрой и качественной разработки программ.
Форматы условного оператора и операторов цикла желательно знать и помнить. Как думает наш уважаемый Читатель, стал бы Г. Каспаров чемпионом мира по шахматам, если бы он каждый раз заглядывал в справочник, чтобы посмотреть, как ходит конь?
127

§ 2.3. Программы с циклами
Программы, в основе которых лежит структура повторения, называются циклическими. Существует три основных разновидности циклов.
Циклически повторяемые действия встречаются очень часто, поскольку в ЭВМ ресурсы памяти ограничены. Для реализации алгоритмической конструкции «Повторение» в Паскале предусмотрены три структурированных оператора цикла.
Вцикле с предусловием или цикле типа «пока» последовательность операторов, расположенная в теле цикла, выполняется до тех пор, пока истинным является условие продолжения цикла.
Вцикле с постусловием или цикле типа «до» выполнение операторов из тела цикла продолжается до того момента, когда условие выхода из цикла станет истинным.
Вцикле с параметром или цикле типа «для» происходит выполнение тела цикла для всех значений некоторой переменной, называемой параметром цикла, в заданном диапазоне.
Цикл с предусловием
Формат оператора цикла с предусловием:
While Булево выражение Do Оператор;
Если булево выражение истинно, то выполняется оператор из тела цикла. Оператор, входящий в тело цикла, часто бывает составным.
В цикле с предусловием сначала происходит проверка истинности условия. Поэтому
128
если изначально оно ложно, то оператор из тела цикла не выполнится ни разу.
Оператор цикла с предусловием часто используется, когда заранее неизвестно число повторений.
Для сравнения синтаксиса операторов цикла рассмотрим одну и ту же задачу, в которой требуется посчитать сумму десяти целых чисел. Числа при этом вводятся в ячейки компонента StringGrid1.
Тогда ключевой фрагмент решения задачи с помощью цикла WHILE … DO … будет иметь вид:
j := 0;
while j<10 do begin
x := StrToInt(StringGrid1.Cells[j,0]); s := s + x; j := j + 1
end;
ShowMessage(IntToStr(s))
Обратите внимание на то, что тело цикла состоит из составного оператора, в котором имеется оператор (j:=j+1), влияющий на изменение значения переменной, входящей в условие продолжения цикла (j<10).
Если в теле цикла не будет оператора, влияющего на условие цикла, то ждать результаты работы такой программы придется долго – произойдет, так называемое, «зацикливание».
Цикл с постусловием
Формат оператора цикла с постусловием:
Repeat Операторы Until Булево выражение;
Тело цикла REPEAT… UNTIL…может состоять из нескольких операторов, отделяемых друг от друга точкой с запятой. Перед UNTIL точку с запятой можно опустить.
129
Цикл с постусловием является циклом типа «до». Если условие выхода из цикла ложно, то выполняется последовательность операторов из тела цикла.
В цикле с постусловием сначала происходит выполнение серии операторов, а затем проверка истинности булева выражения. Поэтому в цикле с постусловием серия операторов всегда будет выполнена хотя бы один раз. Цикл прекращается, когда условие выхода из цикла становится истинным.
Ключевой фрагмент решения задачи о сумме десяти целых чисел с помощью цикла REPEAT… UNTIL… выглядит так:
j:=0; Repeat
x := StrToInt(StringGrid1.Cells[j,0]); s := s + x; j := j + 1
Until j = 10; ShowMessage(IntToStr(s))
Обратите внимание на то, что в теле цикла также имеется оператор (j:=j+1), влияющий на изменение значения переменной, входящей в условие выхода из цикла (j=10).
Цикл REPEAT… UNTIL…обычно используется в том случае, когда количество повторений (итераций) в цикле заранее неизвестно и определяется в процессе работы программы.
Цикл с параметром
Существует две разновидности оператора цикла с параметром.
Формат оператора цикла по возрастанию с параметром:
For Параметр := Начальное значение To Конечное значение
Do Оператор;
Параметром цикла может служить переменная порядкового типа. Начальное и конечное значения параметра – это
130
выражения или значения того же типа, что и параметр цикла. Параметр цикла описывается как обычная переменная в разделе описания переменных.
В операторе цикла с параметром сначала вычисляются начальное и конечное значения параметра. Затем параметру цикла присваивается начальное значение. Потом проводится проверка условия прекращения цикла. Цикл прекращается тогда, когда значение параметра цикла превышает конечное значение. Если цикл не заканчивается, то выполняется оператор из тела цикла. Параметру цикла автоматически присваивается следующее значение (для целого типа – на единицу больше).
Ключевой фрагмент решения задачи о сумме десяти целых чисел с помощью цикла FOR…TO…DO… выглядит так:
For j := 0 To 9 Do begin
x := StrToInt(StringGrid1.Cells[j,0]); s := s + x;
end;
ShowMessage(IntToStr(s))
В теле цикла FOR…TO…DO…не должно производиться никаких действий по изменению параметра!
Формат оператора цикла по убыванию с параметром:
For Параметр := Начальное значение Downto Конечное значение
Do Оператор;
Цикл прекращается тогда, когда значение параметра цикла становится меньше конечного значения. При очередном витке цикла параметру цикла присваивается предыдущее значение (для целого типа – на единицу меньше).
131

Ключевой фрагмент решения задачи о сумме десяти целых чисел с помощью цикла FOR…DOWNTO…DO… выглядит так:
For j := 9 DownTo 0 Do begin
x := StrToInt(StringGrid1.Cells[j,0]); s := s + x;
end;
ShowMessage(IntToStr(s))
В теле цикла FOR…DOWNTO…DO…не производится никаких действий по изменению параметра!
Циклы можно вкладываются друг в друга, как куклыматрешки. Циклы называются вложенными, если в тело одного из них, входит другой оператор цикла. Цикл, содержащий в себе другой цикл, называется внешним. Цикл, содержащийся в другом цикле, называется внутренним.
Внутренний цикл должен завершится раньше, чем внешний!
Внутренний и внешний циклы могут быть одного вида. В качестве параметров вложенных циклов for недопустимо использовать одну и ту же переменную.
Внутренний и внешний циклы могут быть разных видов. Например, допустимо внутри цикла с предусловием использовать цикл с параметром.
В операторах цикла можно досрочно выйти из цикла и принудительно начать новую итерацию (виток цикла). Стандартная процедура Break позволяет принудительно прервать цикл, не дожидаясь выполнения условия выхода. Процедура Continue позволяет принудительно начать новую итерацию цикла, даже если предыдущая еще не завершена.
132

Для циклических программ в качестве исходных данных часто требуется последовательность случайных чисел. Генерация случайных чисел с помощью оператора random выдает псевдослучайную последовательность.
Решение задач по теме «Программы с циклами»
1. Составьте программу для нахождения наименьшего общего кратного двух чисел.
♣ Наименьшее общее кратное чисел а и b найдем как частное произведения этих чисел на их наибольший общий делитель. НОК(a,b)=a*b/НОД(a,b). Наибольший общий делитель найдем по алгоритму Евклида.
Пример оформления программы показан на рис. 2.3.1.
Для ввода целых чисел a и b использованы компоненты
SpinEdit, взятые с закладки Samples.
Рис.2.3.1. Вид окна приложения для решения задачи № 1.
Значение компонента SpinEdit возвращается в программу через свойство Value целого типа. ♠
План примера 1.
1-5. Добавление компонент на форму.
6.Написание обработчика кнопки Выход.
7.Написание обработчика кнопки Результат.
8-10. Исполнение, сохранение и закрытие программы.
133
Пример работы 1: |
|
Подсказка |
||
1. |
В строке заголовка формы напишите НОК |
Свойство Caption |
||
2. |
Положите на форму компонент Panel с над- |
Свойство Caption |
||
писью «Наименьшее общее кратное (НОК)» |
|
|||
3. |
Добавьте два компонента Label с надписями |
Свойство Caption |
||
a и b |
|
|
||
4. |
Справа от меток добавьте два компонента |
Закладка Misc |
||
SpinEdit |
|
|
||
5. |
Положите две командные кнопки Результат и |
Свойство Caption |
||
Выход |
|
|
||
6. |
Напишите обработ- |
|
procedure TForm1.Button2Click (Sender: |
|
чик нажатия кнопки |
|
TObject); |
|
|
Выход |
|
begin |
|
|
|
|
|
Close |
|
|
|
|
end; |
|
7. |
Напишите обработ- |
|
procedure TForm1.Button1Click(Sender: TOb- |
|
чик нажатия кнопки |
|
ject); |
|
|
Результат |
|
var a, b, nod : integer; |
||
|
|
|
begin |
|
|
|
|
a:=Form1.SpinEdit1.Value; |
|
|
|
|
b:=Form1.SpinEdit2.Value; |
|
|
|
|
while (a>0) and (b>0) do |
|
|
|
|
if a>=b |
|
|
|
|
then a:=a mod b |
|
|
|
|
else b:=b mod a; |
|
|
|
|
nod:=a+b; |
|
|
|
|
ShowMessage ('НОК(a,b)='+IntToStr(round |
|
|
|
|
(Form1.SpinEdit1.Value*Form1.SpinEdit2. |
|
|
|
|
Value/nod))); |
|
|
|
|
end; |
|
Процедура ShowMessage(‘текст’) выводит текст, указанный в скобках, в отдельном информационном окне. Параметр процедуры ShowMessage набирается в одной строке!
Символ + соединяет две строки.
Функция IntToStr() переводит целочисленный аргумент в строку. Функция StrToInt () переводит символьную запись числа в целое число.
8. Запустите программу на исполнение |
Запуск Запуск |
134

Введите значения a и b. Нажатие на кнопку Результат должно привести к появлению информационного окна, в котором вычислено наименьшее общее кратное введенных чисел.
Рис.2.3.2. Тестирование приложения для задачи № 1.
Закройте окно и нажмите Выход.
9. Сохраните результаты работы |
Файл Сохранить все |
10. Закройте проект |
Файл Закрыть |
Следующая задача в консольном приложении может быть решена с использованием цикла, а в Lazarus-проекте без него.
2. Пусть вводится последовательность вещественных чисел, оканчивающаяся нулем. Определите, номер числа по абсолютной величине самого близкого к своему номеру.
Рис.2.3.3. Интерфейс приложения для задачи № 2.
♣ Элементы последовательности (вещественные числа) вводятся посредством компонента Edit. Значения этого
135

компонента доступны в основной программе через свойство
Text.
Функция StrToFloat() переводит символьную запись числа в вещественное число. Функция FloatToStr() производит обратное преобразование.
Рис.2.3.4. Вид окна работающего приложения.
Клик по кнопке Ввести приводит к преобразованию значения свойства Text компонента Edit в вещественное число x, изменению номера n элемента последовательности и вычислению e - модуля разности числа и его номера. В переменную res записывается номер элемента с самым маленьким значением e.
Как только вводится 0, под компонентом Edit выводится информация об искомом номере.
Чтобы значения переменных n, e, res не обнулялись при каждом обращении к обработчику нажатия кнопки Ввести, переменные должны быть глобальными, т.е. должны быть объявлены не в процедуре, а в основной программе. ♠
План примера 2. 1-5. Добавление компонент на форму.
6.Написание обработчика кнопки Выход.
7.Объявление глобальных переменных.
8.Написание обработчика кнопки Ввести.
9-10. Исполнение, сохранение и закрытие программы.
136

Пример работы 2: |
|
Подсказка |
|||
1. |
В строке заголовка формы напишите Пример |
Свойство Caption |
|||
2. |
Положите на форму компонент Label1 с надписью |
Свойство Caption |
|||
«Вводите элементы последовательности и нажимай- |
|
||||
те кнопку Ввести» |
|
|
|
Очистите свойство Cap- |
|
3. |
Положите на форму компонент Label2 |
||||
|
|
|
|
|
tion |
4. |
Добавьте компонент Edit. Очистите свойство Text |
Закладка Standard |
|||
5. |
Положите две командные кнопки Ввести и Выход |
Свойство Caption |
|||
6. |
Напишите |
procedure TForm1.Button2Click |
(Sender: TObject); |
||
обработчик на- |
begin |
|
|
||
жатия кнопки |
Close |
|
|
||
Выход |
end; |
|
|
||
7. |
Опишите гло- |
var |
|
|
|
бальные пере- |
Form1: TForm1; |
|
|||
менные n, res, e. |
e:real; n,res:byte; |
|
|||
8. |
Напишите |
procedure TForm1.Button1Click(Sender: TObject); |
|||
обработчик на- |
var x:real; |
|
|
||
жатия кнопки |
begin |
|
|
||
Ввести |
n:=n+1; |
|
|
||
|
|
x:=StrToFloat(Form1.Edit1.Text); |
|||
|
|
if x=0 |
|
|
|
|
|
then |
|
|
|
|
|
begin |
|
|
|
|
|
Form1.Label2.Caption:='Искомый номер равен '+ |
|||
|
|
IntToStr(res); res:=0; n:=0 |
|||
|
|
end |
|
|
|
|
|
else |
|
|
|
|
|
if n=1 |
|
||
|
|
then begin e:=abs(x-n); res:=n end |
|||
|
|
else |
|
|
|
|
|
if abs(x-n)<e |
|
||
|
|
then begin e:=abs(x-n); res:=n |
|||
|
|
end; |
|
|
|
|
|
end; |
|
|
|
9. |
Запустите программу на ис- |
|
Запуск Запуск |
|
|
полнение |
|
|
|
|
|
10. Сохраните результаты рабо- |
|
Файл Сохранить все |
|||
ты |
|
|
|
|
3. Составьте программу для нахождения всех прямоугольников заданной площади. Считайте, что длины сторон прямоугольников и площадь выражаются натуральными числами.
137

Рис.2.3.5. Вид окна приложения для решения задачи № 3.
procedure TForm1.MenuItem2Click(Sender: TObject); begin
close; // закрытие окна приложения end;
procedure TForm1.Button1Click(Sender: TObject); var s, i : integer;
begin
{Ввод значения площади} s := StrToInt(Edit1.Text);
{Очистка Еdit от предыдущих значений}
Edit2.Text:=' ';
Edit3.Text:=' ';
{Присваиваем переменной i значения от 1 до s} for i := 1 to s do
begin
{Если остаток от целочисленного деления s на i = 0, то выводим получившиеся значения сторон}
138

if s mod i = 0 then begin
Edit2.Text:=Edit2.Text+' '+IntToStr(i);
{значения одной стороны a}
Edit3.Text:=Edit3.Text+' '+IntToStr(s div i);
{значения другой стороны b} end;
end;
end;
4. Вычислите y = 1!+ 2 !+ 3!+ n !, n > 1 .
Рис.2.3.6. Вид окна приложения для решения задачи № 4.
procedure TForm1.Button1Click(Sender: TObject); var i,n: integer; y: real;
function fact (x: integer) : real;
// создание пользовательской функции для вычисления факториала аргумента х
var i: integer; s: real; begin
s := 1;
139

for i := 1 to x do s := s * i; fact := s;
end; begin
y := 0;
n := StrToInt(Edit1.Text);
for i := 1 to n do y := y + fact(i); Edit2.Text := FloatToStr(y);
end;
5. Напечатайте все простые трехзначные числа.
Рис.2.3.7. Вид окна приложения для решения задачи № 6.
procedure TForm1.Button1Click(Sender: TObject); const a = 999;
var i, j, b : integer;
140

begin
for i := 100 to a do begin
j:=2;
b:=round(sqrt(i));
while (i mod j <> 0) and (j <= b) do inc( j ); if (j > b) then Form1.ListBox1.Items.Add(IntToStr(i)); end;
end;
6. Составьте программу, которая проверяет, является ли заданное число совершенным. Совершенным называется натуральное число, равное сумме всех своих делителей (исключая само число). Например, 28=1+2+4+7+14.
Рис.2.3.8. Вид окна приложения для решения задачи № 6.
procedure TForm1.Button1Click(Sender: TObject);
141

var i, num, sum : integer; begin
num := StrToInt(Edit1.Text); if num>0 then
begin sum:=0; i:=1;
while(i<num-1)and(sum<=num)do begin
if(num mod i)=0 then sum:=sum+i; i:=i+1;
end;
if sum=num then ShowMessage ('Число' + IntToStr(num) + 'является совершенным!!!')
else ShowMessage('Число'+IntToStr(num) + 'НЕ является совершенным!!!');
end
else ShowMessage ('Введите корректные данные'); end;
7. Дано 50 случайных чисел из диапазона от 0 до n. Вычислите разность между минимальным и максимальным числами.
Рис.2.3.9. Вид окна приложения для решения задачи № 7.
142
procedure TForm1.Button1Click(Sender: TObject);
// генерация случайных чисел var j : byte;
begin randomize;
For j:=0 To 49 Do
StringGrid1.Cells[j,0] := IntToStr (random (StrToInt (Edit1.text))+1)
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
// поиск максимального и минимального из чисел var max, j, min: integer;
begin max:=0;
min:=StrToInt(StringGrid1.Cells[0,0]); for j:=0 to 49 do
begin
if StrToInt (StringGrid1.Cells[j,0])>max then max:=strtoint(StringGrid1.Cells[j,0]);
if StrToInt (StringGrid1.Cells[j,0])<min then min:= StrToInt (StringGrid1.Cells[j,0]);
end;
Edit2.caption:='max: '+IntToStr(max)+'; min: ' + IntToStr(min) + '; Их разница: ' + IntToStr(max-min); end;
Во второй части учебного пособия авторы планируют рассмотреть такие темы, как процедуры и функции, рекурсия, строки, записи, множества, файлы, динамические структуры данных и графика в Lazarus.
Авторы будут благодарны читателям за советы и рекомендации по улучшению пособия, прислать которые можно по по адресу: hlivnenko_lv@mail.ru
143
БИБЛИОГРАФИЧЕСКИЙ СПИСОК
1.Алексеев Е.Р. Free Pascal и Lazarus: Учебник по программированию / Е.Р. Алексеев, О.В. Чеснокова, Т.В. Кучер. - М. : ALT Linux ; Издательский дом ДМК-пресс, 2010.
2.Орлик С.В. Секреты Delphi на примерах / С.В. Орлик -
М.: Бином, 1996.
3.Программирование на языке Паскаль: задачник/под ред. Усковой О.Ф. – СПб: Питер, 2002.
4.Фаронов В.В. Delphi3. Учебный курс / В.В. Фаронов.- М.: Нолидж, 1998.
5.Фаронов В.В. Turbo Pascal 7.0. Начальный курс: учеб. Пособие / В.В. Фаронов. – М.: Нолидж, 1998.
6.http://win-ni.narod.ru/FPC/ Путевые заметки при изучении
Free Pascal и Lazarus.
7.http://www.freepascal.org Сайт разработчиков FreePascal.
8.http://www.lazarus.freepascal.org/ Сайт разработчиков
Lazarus.
9.http://www.freepascal.ru/ Информационный портал для разработчиков
144
ОГЛАВЛЕНИЕ |
|
Введение |
3 |
Глава 1. БЫСТРЫЙ СТАРТ |
6 |
§ 1.1. Введение в объектно-ориентированное |
|
программирование |
6 |
Интегрированная среда разработки |
14 |
§ 1.2. Компоненты закладки Standard |
28 |
Компоненты Label, Edit, Memo, ListBox, |
|
ComboBox, Button, Panel, GroupBox |
31 |
Компоненты RadioButton, RadioGroup, |
|
CheckBox, ScrollBar |
39 |
Компоненты MainMenu и PopupMenu |
45 |
§ 1.3. Компоненты закладки Additional |
51 |
Подключение форм. Компонент BitBtn |
51 |
Компоненты Bevel, Image, Shape, |
|
SpeedButton |
59 |
Компоненты LabeledEdit, MaskEdit и |
|
StringGrid |
66 |
Компонент ScrollBox. Запись и |
|
считывание из файла |
71 |
Глава 2. ОСНОВЫ АЛГОРИТМИЗАЦИИ |
78 |
§ 2.1. Линейные программы |
80 |
Общие сведения о Free Pascal |
81 |
Числовые типы данных. Арифметические |
|
выражения |
86 |
145
Оператор присваивания, особенности |
|
ввода и вывода информации в |
|
приложениях Lazarus |
90 |
Составление линейных программ |
92 |
Ключевые фрагменты решения задач |
|
по теме «Линейные программы» |
95 |
§ 2.2. Ветвления в программах |
101 |
Логический тип. Логические операции. |
|
Операции отношения. Булевы |
|
выражения |
101 |
Составной оператор. Условный |
|
оператор. Оператор безусловного |
|
перехода. Оператор выбора |
104 |
Решение задач по теме «Ветвления в |
|
программах |
113 |
§ 2.3. Программы с циклами |
128 |
Цикл с предусловием |
128 |
Цикл с постусловием |
129 |
Цикл с параметром |
130 |
Решение задач по теме «Ветвления в |
|
программах |
133 |
Библиографический список |
144 |
146