Выводы по проделанной работе. 2 страница

Обратите внимание на выравнивание операторов в приведенных примерах! Очень легко поддается пониманию программа, в которой все операторы выровнены надлежащим образом.

Представьте, что в предыдущем примере не было произведено выравнивание операторов, например:

case n of

1:........

2:

Begin

if not Flagthen

Writeln ('Данные не введены, выполните пункт №1');

Else

Begin

if X > 0 then

Y := 1 / X

Else

Y := X * X;

Writeln('При X = ', X:7:2, ' Y = ', Y:7:2);

End;

end;

3: Exit;

End;

В таком виде разобраться с данным примером практически невозможно. Выравнивание должно быть выполнено таким образом, чтобы вложенные группы операторов имели отступ вправо относительно внешних операторов (рекомендуется 2 пробела). Помните, что каждый BEGIN должен иметь завершающий END, причем их следует располагать на одной вертикальной линии. Все, что находится внутри операторных скобок BEGIN..END, должно смещаться вправо.

2.8. Варианты заданий

1) Вычислить объем параллелепипеда со сторонами A, B, C и определить, является ли данное геометрическое тело кубом.

2) Вычислить площадь треугольника со сторонами А, В, С. Перед вычислением площади проверить условие существования треугольника с заданными сторонами.

3) Вычислить площадь треугольника со сторонами A, B, C. Определить, является ли треугольник равнобедренным.

4) Вычислить площадь прямоугольника со сторонами A и B и определить, является ли данная фигура квадратом.

5) Составить программу нахождения корней квадратного уравнения у=ах2+bх+с.

6) Определить, можно ли сделать круглую заготовку с заданным радиусом R из квадратного листа фанеры с заданной стороной A.

7) Определить, хватит ли имеющейся суммы S на покупку N-го количества товара (при известной цене товара).

8) Определить, можно ли сделать две квадратных заготовки со стороной А из листа железа прямоугольной формы со сторонами В и С.

9) Определить, достаточно ли имеющейся ткани для изготовления изделий двух видов, если известны: расход ткани на каждое изделие, количество изделий каждого вида, количество имеющейся ткани.

10) Рассчитать сумму оплаты за потребленную энергию, если известны: стоимость 1 квт/час, расход энергии, коэффициент льгот (льготы могут отсутствовать).

11) Определить, достаточно ли бензина для поездки, если известны: длина пути, количество бензина в баке и расход бензина на 1 км.

12) Определить, будет ли начислена студенту стипендия по результатам экзаменов (стипендия начисляется, если все экзамены сданы на «хорошо» и «отлично»), если известны оценки по всем экзаменам.

13) Определить, будет ли зачислен абитуриент в студенты по результатам вступительных экзаменов, если известны: проходной балл; количество баллов, набранных абитуриентом по каждому экзамену.

14) Определить, изделия какой из двух групп товаров выгоднее сшить из одного рулона ткани, если известны: расход ткани на каждое изделие и цена готового изделия, количество метров в рулоне.

15) Определить, выполнен ли план по продаже товара за день, если известны: план продажи (в рублях), количество проданного товара и цена товара.

16) Определить, операции с какой из двух валют составили большую прибыль, если известны: курс продажи, количество продаж по каждой валюте.

17) Определить наибольшую выручку от продажи трех видов товаров, если известны: цена товара; количество проданных товаров каждого вида.

18) Определить количество корней уравнения y=ax2+bx+c.

19) Определить, является ли число А четным или нечетным.

20) Вычислить площадь треугольника со сторонами A, B, C и определить, является ли данный треугольник равносторонним.

2.9. Содержание отчета (см. пункт 1.11)

2.10. Контрольные вопросы

1) Назначение, формы записи и порядок выполнения оператора IF.

2) Особенности использования вложенных условных операторов.

3) Каковы отличия оператора выбора CASE от оператора условия IF?

4) Какие правила должны выполняться при использовании оператора выбора CASE?

5) Назначение и особенности оператора безусловного перехода.

6) Для чего нужна отладка программы?

7) Как выполнять программу в пошаговом режиме?

8) Как поставить и как отменить точки останова?

9) Как выполнить программу «до курсора»?

10) Как открыть окно Watch?

11) Как внести переменную в окно Watch?

Лабораторная работа №3. Разработка циклической программы с известным количеством повторений

3.1. Цель работы

Целью работы является освоение процесса разработки циклических программ с заданным (известным) числом повторений на языке Pascal.

3.2. Задание на лабораторную работу

Разработать программу с использованием оператора цикла FOR, осуществляющую следующие действия:

а) Вычисление заданной величины (суммы N слагаемых, произведения N сомножителей и т.п.);

б) Обработка данных с использованием двумерных массивов.

3.3. Требования к программе

Программа должна выводить:

– номер варианта, назначение программы и ФИО автора;

– меню выбора действия программы («а» или «б»); допускается сделать две отдельные программы без меню выбора;

– информационные сообщения о необходимости ввода данных;

– сообщение с результатами, полученными в ходе работы программы;

3.4. Порядок выполнения работы

1) Получить вариант задания (п. 3.8).

2) Изучить принцип действия FOR при разработке циклических программ на языке Pascal (п. 3.5).

3) Составить и отладить программу вычисления заданной величины (суммы N слагаемых, произведения N сомножителей и т.п.) в соответствии с подпунктом «а» варианта задания.

4) Изучить основы работы с данными типа «массив» (ARRAY) на языке Pascal (п. 3.6).

5) Разработать и отладить программу обработки данных с использованием двумерных массивов в соответствии с подпунктом «б» варианта задания.

6) Объединить обе разработанные программы в одну с использованием меню выбора (п. 3.7).

7) Ответить на контрольные вопросы (п. 3.10).

8) Оформить отчет (см. п. 1.11)

3.5. Оператор цикла FOR

Очень часто перед программистом стоит задача организовать работу программы таким образом, чтобы некоторый участок кода выполнялся многократно (с заданным количеством повторений). В языке Pascal для этой цели предусмотрен оператор FOR, имеющий 2 формы записи:

1) for I := N1 to N2 do <тело цикла>;

2) for I := N1 downto N2 do <тело цикла>;

Цикл FOR работает следующим образом. Вначале программа определяет значение переменных (выражений) N1 и N2. Далее переменная цикла I (счетчик цикла) получает начальное значение N1. После этого осуществляется сравнение переменной I с конечным значением N2 и если переменная I его не превышает (для первой формы FOR) либо если I больше или равно N2 (для второй формы FOR), то выполняется «тело цикла», т.е. заданный оператор (или группа операторов в BEGIN..END). После того, как тело цикла было выполнено, управление вновь переходит к оператору FOR, переменная I получает новое значение (на единицу больше, либо на единицу меньше, чем в прошлый раз), далее осуществляется ее сравнение с N2 и принимается решение о том, следует ли еще раз выполнить тело цикла.

Ниже представлены примеры для обеих форм оператора FOR. Программа осуществляет перемножение заданной переменной Num с текущим значением счетчика цикла J и выводит на экран результат вычисления выражения, порядковый номер итерации и значение счетчика цикла.

var Num, J: Integer; begin Num := 3; {объявляем цикл «вверх» от 1 до 5} for J := 1 to 5 do begin {Выводим результат умножения на экран } Writeln(J, ') ', Num, '*', J, '=', Num * J); {Выполняем умножение} Num := Num * J; end; end. Результаты: 1) 3*1=3 2) 3*2=6 3) 6*3=18 4) 18*4=72 5) 72*5=360    
var Num, J, K: Integer; begin Num := 7; K := 1; {порядковый № итерации} {объявляем цикл «вниз» от 9 до 6} for J := 9 downto 6 do begin {Выводим результат умножения на экран} Writeln(K, ') ', Num, '*', J, '=', Num * J); {Выполняем умножение} Num := Num * J; K := K + 1; {Увеличиваем порядковый номер} end; end. Результаты: 1) 7*9=63 2) 63*8=504 3) 504*7=3528 4)3528*6=21168    

Поскольку во втором примере используется оператор FOR с downto, а переменная J (счетчик цикла) изменяет свое значение от 9 до 6, то для определения порядкового номера итерации пришлось добавлять новую переменную «K». В первом примере этого не требовалось, поскольку счетчик цикла J изменяется от 1 до 5, а эти значения соответствуют номеру итерации.

Следующий пример демонстрирует использование цикла FOR для вычисления суммы Выводы по проделанной работе. 2 страница - student2.ru (слева) и произведения Выводы по проделанной работе. 2 страница - student2.ru (справа):

const n = 5; {Количество шагов} var I: Integer; Res, X: Real; begin X := 10; {Ввод Х} Res := 0; {Обнуление Res} for I := 1 to n do Res := Res + I * (X * X); Writeln('Res = ', Res:8:2); end. const n = 4; {Количество шагов} var I: Integer; Res, X: Real; begin X := 15; {Ввод Х} Res := 1; {Присвоение единицы} for I := 1 to n do Res := Res * (X + I * I * I); Writeln('Res = ', Res:8:2); end.

При использовании оператора FOR необходимо учитывать следующие замечания:

– переменная цикла (счетчик числа), а также выражения N1 и N2 должны иметь порядковый тип. Дробный тип REAL не допускается. В большинстве случаев для объявления счетчика цикла используется тип INTEGER;

– внутри тела цикла запрещено изменение переменной цикла;

– значение переменной цикла является актуальным только внутри тела цикла; после завершения работы цикла значение переменной цикла является неопределенным, т.е. установленным случайным образом;

– переменную цикла можно использовать повторно, например, при программировании других циклов.

Следующий пример демонстрирует печать на экране участка функции косинуса Cos. При этом используются 2 цикла FOR: внешний (со счетчиком цикла I) и внутренний (со счетчиком цикла J):

program Cosinus; const Pi = 3.14159; {Константа Pi} {Границы внешнего цикла в градусах} MaxGradus = 90; var I, J: Integer; Rad, Value: Real; begin {Внешний цикл по I (от -90 до +90)} for I := -MaxGradus to MaxGradus do begin {Учитываются только градусы, кратные 5} if I mod 5 = 0 then begin {Пересчет градусов в радианы} Rad := Pi * I / 180; {Вычисление косинуса. В результате Value} {будет иметь значение от 0 до 1} Value := Cos(Rad);   {Внутренний (вложенный) цикл (по J)} {Печатает на экране от 1 до 20 пробелов} {Round округляет число до целого} for J := 1 to Round(Value * 20) do Write(' ');   {Печать символа «*»} Writeln('*'); end; end; Readln; {ожидание нажатия ENTER} end. Выводы по проделанной работе. 2 страница - student2.ru

Ниже представлены необходимые пояснения к данному примеру:

1) Переменная внешнего чикла I меняет на каждой итерации значение, начиная с –90 и заканчивая +90. Этот диапазон выбран не случайно, поскольку функция Cos будет иметь в этом диапазоне только положительные значения от 0 до 1.

2) Операция «mod» возвращает остаток от деления двух целых чисел. Условие «if I mod 5 = 0 then» будет выполнено только в том случае, если значения I кратны 5 (т.е. -90, -85, -80,…, -10, -5…0, 5, 10…, 85, 90). Таким образом, символ «*» будет печататься на экране не для каждого градуса. Это сделано для того, чтобы весь график косинуса поместился на экране. Вместо 180 символов «*» на экране печатается только 37 символов.

3) Cos – это функция, принимающая в качестве аргумента величину угла, выраженную в радианах, и возвращающая значение косинуса в диапазоне от –1 до +1. Перед вызовом функции «Cos» осуществляется преобразование градусов в радианы: Rad := Pi * I / 180.

4) В примере присутствует дополнительный цикл FOR со счетчиком J. Он расположен внутри тела другого цикла, т.е. является «вложенным» или «внутренним». Он служит для заполнения строки пробелами. В зависимости от вычисленного значения косинуса, внутренний цикл выполняется от нуля до 20 раз, т.к. переменная Value в данном примере может иметь значения от 0 до 1.

5) Для печати символа «*» используется оператор Writeln.

6) Оператор Readln, указанный в программе без скобок, приостанавливает программу до тех пор, пока пользователь не нажмет Enter. При этом никакого ввода данных не происходит. Это избавляет от необходимости нажимать Alt+F5 для просмотра результатов работы программы.

Важно отметить, что наименование переменной вложенного цикла должно отличаться от переменной внешнего цикла. Глубина вложенности циклов FOR может быть любой, однако на практике не приветствуется слишком большая вложенность, поскольку ухудшается читабельность кода. В таких случаях рекомендуется использовать методы процедурного программирования.

При необходимости можно досрочно прервать работу цикла. Для этого следует вызвать оператор Break. В том случае, если требуется пропустить операторы тела цикла и перейти к следующей итерации, следует вызвать оператор Continue. Не рекомендуется злоупотреблять оператором Continue, поскольку его использование ухудшает читабельность кода, тем более из любой ситуации можно выйти, не используя Continue. Оператор Break, вызванный из вложенного цикла, не прерывает работу внешнего цикла.

На рисунке 3.1 представлен пример участка схемы алгоритма, соответствующего циклу с известным числом повторений.

Выводы по проделанной работе. 2 страница - student2.ru

Рисунок 3.1 – Схема алгоритма участка программы с циклом for

Возведение в степень

В языке Pascal отсутствует операция возведения в степень. Для возведения любого числа в целую, положительную степень вы можете использовать следующий код:

{Пример демонстрирует возведение числа X в степень N}

program Stepen;

Var

X, Res: Real;

N, I: Integer;

Begin

{*** Ввод данных ***}

Write('Введите значения X и N:');

Readln(X, N);

{*** Возведение в степень ***}

Res := 1; {Присваиваем начальное значение переменной Res}

for I := 1 to N do{Цикл возведения в степень}

Res := Res * X;

{*** Вывод результата на экран ***}

Writeln('X^N=', Res:5:2);

end.

Цикл возведения в степень целесообразно применять, если значение степени заранее неизвестно.

Если требуется возвести число в квадрат или в куб, то проще поступить следующим образом: Y := X * X или Y := X * X * X.

Для возведения числа «–1» в целую, положительную степень рекомендуется следующий код:

if Odd(N) then{Если число нечетное... }

Y := –1

else {Иначе (если число четное)... }

Y := 1;

Odd – это функция, возвращающая логический результат True, если аргумент является нечетным числом, иначе возвращает False.

3.6. Тип данных «массив» – объявление и использование

Массив — упорядоченный набор данных для хранения множества элементов одного типа, идентифицируемых с помощью одного или нескольких индексов. Количество используемых индексов массива может быть различным. Массивы с одним индексом называют одномерными, с двумя — двумерными и т.д. Одномерный массив соответствует вектору в математике, двумерный — матрице. Массивы с числом измерений > 2 встречаются редко.

Формат объявления переменных типа «массив» представлен ниже:

Var

<список переменных> = array[<индексы>] of <тип данных>;

где <список переменных> – наименование одной или нескольких переменных (через запятую);

<индексы> – описание диапазона индексов для каждого измерения массива, например:

- [1..10] – соответствует одномерному массиву (вектору), первый элемент которого имеет индекс «1», а последний «10» (всего 10 элементов);

- [0..4] – соответствует одномерному массиву, первый элемент которого имеет индекс «0», а последний «4» (всего 5 элементов);

- [1..5, 1..4] – соответствует двухмерному массиву (матрице), состоящему из 5 строк (индексация от 1 до 5) и 4 столбцов (индексация от 1 до 4);

<тип данных> – любой тип данных, известный компилятору Pascal, например, Integer, Byte, Real, Boolean, Char, string, а также типы данных, объявленные программистом.

Ниже приведены примеры объявления переменных типа «массив»:

{2 вектора из 10 элементов типа Integer. Индексация начинается с «1»}

Vect1, Vect2: array[1..10] of Integer;

{Матрица вещественных чисел 8 х 6. Индексация начинается с «0»}

Matr: array[0..7, 0..5] of Real;

{Список из 20 строк. Индексация начинается с «1»}

StrList: array[1..20] of string;

Во многих случаях более удобным является однократное объявление типа данных «массив» в начале программы (в секции type). Объявленный таким способом тип данных в дальнейшем можно использовать при описании переменных. Данный способ имеет следующие преимущества:

- при необходимости внесения изменений в объявление массива достаточно это сделать в одном месте;

- переменные, объявленные в секции var с использованием отдельного типа, являются совместимыми, т.е. между ними допускается операция присвоения «:=»;

- при использовании в программе процедур и функций у программиста появляется возможность объявления параметров процедуры, имеющих тип «массив».

Ниже представлен пример объявления нового типа данных «массив», а также переменных этого типа:

Type

{Объявление нового типа данных «матрица»}

TMatrix = array[1..10, 1..20] of Real;

Var

{Объявление переменных типа TMatrix}

Matrix1, Matrix2, Matrix3: TMatrix;

.......................................

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

{Установка нового значения 3-го элемента вектора}

Vect[3] := 3.45; {Установка заданного числового значения}

Vect[3] := Random; {Установка случайного значения}

Readln(Vect[3]); {Значение вводится пользователем с клавиатуры}

{Чтение 2-го элемента вектора}

Value := Vect[2]; {Присвоение в переменную Value}

Writeln(Vect[2]); {Вывод на экран}

{Вычисление суммы первых трех элементов}

Summa := Vect[1] + Vect[2] + Vect[3];

Ниже приведены примеры чтения и записи элементов двухмерного массива (матрицы):

{Установка заданного значения элемента матрицы с координатами 4, 3}

{индекс 4 – это номер строки матрицы, 3 – номер столбца матрицы}

Matrix[4, 3] := 123.456;

Readln(Matrix[2, 4]); {Ввод элемента (2, 4) с клавиатуры}

Writeln(Matrix[I, J]); {Вывод элемента (I, J) на экран}

В качестве индекса элемента массива может выступать явно указанное целое значение, либо целочисленная переменная. Чаще всего обработка элементов массива выполняется в цикле, поэтому в качестве индекса используется переменная-счетчик цикла, например:

for I := 1 to 10 do {цикл по I от 1 до 10}

Vect[I] := Random; {I-му элементу присваивается случайное число}

В приведенном ниже примере осуществляется заполнение элементов матрицы случайными числами с помощью функции Random, вывод полученных значений на экран, также осуществляется поиск наибольшего значения и вывод его (вместе с координатами) на экран.

program FindMaxElement;

const {Объявление констант}

Rows = 5; {Число строк матрицы}

Cols = 4; {Число столбцов матрицы}

Var

{Объявление массива размером Rows x Cols}

Mas: array[1..Rows, 1..Cols] of Real;

I, J: Integer; {Объявление переменных цикла}

MaxValue: Real; {Максимальное значение}

MaxRowIndex: Integer; {Номер строки максимального значения}

MaxColIndex: Integer; {Номер столбца максимального значения}

Begin

{Цикл заполнения массива и вывода элементов на экран}

for I := 1 to Rows do {Цикл по I (перебор строк матрицы)}

begin {можно было обойтись и без этого begin..end }

for J := 1 to Cols do {Цикл по J (перебор столбцов матрицы)}

begin {а этот begin..end требуется обязательно}

{Присваиваем элементу (I, J) случайное значение}

Mas[I, J] := Random;

{Печатаем значение элемента (все - на одной строке)}

Write(Mas[I, J]:8:2, ' ');

if J = Cols then {Если это последний столбец, }

Writeln; {то осуществляем перевод строки}

end;

end; {Данный begin..end здесь - для улучшения читабельности кода}

{Перед началом поиска максимального значения переменная

MaxValue уже должна иметь любое значение, но это значение

не должно быть больше, чем элементы матрицы. Поэтому

достаточно взять в качестве первоначального значения

любой элемент матрицы Mas, например самый первый}

MaxValue := Mas[1, 1]; {Запоминаем первый элемент}

MaxRowIndex := 1; {Запоминаем номер строки 1-го элемента}

MaxColIndex := 1; {Запоминаем номер столбца 1-го элемента}

{Цикл поиска максимального элемента}

for I := 1 to Rows do {Цикл по I (перебор строк матрицы)}

for J := 1 to Cols do {Цикл по J (перебор столбцов матрицы)}

Begin

{Если текущий элемент (I, J) больше, чем MaxValue,

то записываем этот элемент в MaxValue и сохраняем его координаты}

if Mas[I, J] > MaxValue then

Begin

MaxValue := Mas[I, J];

MaxRowIndex := I;

MaxColIndex := J;

end;

end;

{Выводим найденные значения на экран}

Writeln('Max value=', MaxValue:8:2, '; Row=',

MaxRowIndex, '; Col=', MaxColIndex);

Readln;

end.

Данный пример весьма прост и снабжен подробными комментариями. Очень важно детально разобраться с данным примером, поскольку от этого зависит успешность выполнения задания из варианта (п. 3.8).

3.7. Использование меню для объединения подзадач а и б.

program Laba3;

Label

M1; {Объявление метки безусловного перехода M1}

Var

SubTask: Char; {Переменная типа Char (символ)}

{**** Здесь разместить дополнительные необходимые переменные ****}

Begin

Writeln('Выберите одну из подзадач:');

Writeln('a – вычисление заданной величины в цикле');

Writeln('b – обработка элементов матрицы');

Writeln('e – выход из программы');

M1:

Write('Введите символ:');

Readln(SubTask); {Ожидаем ввод любого символа}

case SubTask of

'a', 'A':

begin {Если ввели букву "a" или "A", то выполнится эта ветка}

Writeln('a) – вычисление заданной величины в цикле');

{******* Здесь разместить операторы, необходимые

для выполнения подзадачи "а" *******}

end;

'b', 'B':

begin {Если ввели букву "b" или "B", то выполнится эта ветка}

Writeln('b) - обработка элементов матрицы ');

{******* Здесь разместить операторы, необходимые

для выполнения подзадачи "б" *******}

end;

'e', 'E':

begin {Если ввели английскую "e" или "E", то закрываем программу}

Exit;

end; {begin..end здесь указывать не обязательно}

else {Для этого ELSE (от CASE) не нужен дополнительный begin..end }

{Если ввели любой другой символ, то выполнится эта ветка}

Writeln('Введен недопустимый символ!');

Writeln('Вы должны повторить ввод!');

goto M1; {Переход на метку M1}

end;

Readln; {Ожидание нажатия Enter}

end.

Данный пример не должен вызывать вопросов, поскольку сочетает в себе элементы кода, которые были в достаточной степени разобраны в предыдущих лабораторных работах.

Следует отметить, что Char – порядковый тип данных, обеспечивающий представление 256 символов, в том числе цифр, знаков препинания, всех больших и малых букв латинского алфавита, а также одного дополнительного алфавита (например, кириллицы).

3.8. Варианты заданий

1.а) Вычислить n!

б) Определить количество элементов матрицы, значения которых не превышают заданное число.

2.а) Вычислить Выводы по проделанной работе. 2 страница - student2.ru .

б) Найти минимальный элемент матрицы.

3.а) Вычислить Выводы по проделанной работе. 2 страница - student2.ru .

б) Найти максимальный элемент матрицы.

4.а) Вычислить Выводы по проделанной работе. 2 страница - student2.ru .

б) Поменять местами минимальный и максимальный элемент матрицы.

5.а) Вычислить Выводы по проделанной работе. 2 страница - student2.ru .

б) Поменять местами два заданных элемента матрицы.

6.а) Вычислить Выводы по проделанной работе. 2 страница - student2.ru .

б) Поменять местами две заданных строки матрицы.

7.а) Вычислить Выводы по проделанной работе. 2 страница - student2.ru .

б) Транспонировать матрицу А.

8.а) Вычислить Выводы по проделанной работе. 2 страница - student2.ru .

б) Сформировать массив В, содержащий сумму элементов каждого столбца матрицы А.

9.а) Вычислить Выводы по проделанной работе. 2 страница - student2.ru .

б) Поменять местами два заданных столбца матрицы.

Наши рекомендации