Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
С какой целью разрабатывают процедуры и функции пользователя?
Какова структура описания процедур пользователя?
Какова структура описания функций пользователя?
В чём отличие между процедурой и функцией?
В каком разделе модуля описывают процедуры и функции?
В чём отличие между локальными и глобальными параметрами?
В чём отличие между формальными и фактическими параметрами?
В чём отличие между параметром-значение и параметром-переменная?
Можно ли фактический параметр функции задать в виде выражения и почему?
Можно ли фактический параметр-переменная процедуры задать в виде выражения и почему?
Можно ли фактический параметр-значение процедуры задать в виде выражения и почему?
В каких случаях фактический параметр процедуры может быть обращением к функции?
Целью работы является приобретение навыков построения циклических алгоритмов и реализация с их помощью основных управляющих конструкций повторения.
Используя Вашу функцию из работы 4, разработайте программу, содержащую:
Задание выполните с использованием различных операторов повторений в двух вариантах: 1 - для постоянного количества элементов массивов; 2 для переменного количества элементов массивов.
Для построения алгоритмов повторения (циклических алгоритмов) используют счётный оператор цикла For, оператор цикла с предусловием While, оператор цикла с постусловием Repeat.
Счётный оператор цикла For
Оператор For реализует следующий алгоритм:
For Счётчик := Начальное_Значение to Конечное_Значение
do Оператор
Счётчик - переменная порядковых типов, к которым относят целые, символьные, перечисляемые. Счётчик последовательно принимает значения от Начальное_Значение до Конечное_Значение с шагом +1.
Для счётчика в этом случае обязательно выполнение условия:
Начальное_Значение < Конечное_Значение
Начальное_Значение и Конечное_Значение - константы, переменные, элементы массива, арифметические выражения, обращение к функции перечисляемых типов.
При входе в оператор цикла переменная Счётчик получает значение равное Начальное_Значение; выполняется оператор, находящийся в теле цикла; затем управление передаётся в начало цикла; значение переменной Счётчик увеличивается на +1; снова выполняется оператор, находящийся в теле цикла. Последний раз оператор, находящийся в теле цикла, выполняется при значении переменной Счётчик, равном Конечное_Значение.
Если в цикле необходимо выполнить не один, а несколько операторов, то используют вложенный оператор Begin ..end;
For Счётчик := Начальное_Значение to Конечное_Значение do begin Оператор 1; ................. end; |
For J := 1 to 10 do begin ........... Оператор 1; ............ end; |
Если Начальное_Значение < Конечное_Значение, то запись оператора примет вид:
For Счётчик := Начальное_Значение Downto Конечное_Значение do Оператор 1; |
For J := 10 downto 1 do Оператор 1;
|
Оператор цикла с предусловием While .. do
Это универсальный управляющий оператор, с его помощью можно реализовать практически любые повторяющиеся действия:
|
Тело цикла состоит из одного оператора |
Тело цикла состоит из нескольких операторов |
|
While Условие do Оператор; |
While Условие do begin Оператор; ............ end; |
Условие - выражение логического типа. При входе в цикл вычисляется значение Условие. Если значение Условие = True, то выполняются операторы, расположенные в теле цикла. Вычисления повторяют до тех пор, пока очередное вычисление не даст результат Условие = False. Работа цикла завершается, и управление передаётся следующему за ним оператору.
Оператор цикла с постусловием Repeat .. until
Repeat
оператор;
...............
оператор;
until Условие;
В отличие от While, в операторе Repeat Условие вычисляется в конце цикла. Операторы, находящиеся в цикле Repeat, будут выполняться пока Условие не примет значение True. В любом случае операторы, входящие в цикл, будут выполнены как минимум один раз.
Массивы структура данных, имеющая общий идентификатор и представляющая собой упорядоченную по номерам совокупность однотипных элементов. Массивы бывают одномерными и многомерными.
Одномерные массивы
Описание типа одномерного массива задают следующим образом:
<Имя_Ттипа> = array [ <индексы> ] of <тип> где,
<Имя_Типа> - идентификатор;
array, of - зарезервированные слова (массив, из);
<индексы> - определяют количество элементов массива и их нумерацию, квадратные скобки - требование синтаксиса. Обычно в качестве индексов используют тип-диапазон, в котором задают границы изменения индексов. В общем случае можно использовать любые порядковые типы, имеющие мощность не более 2 Гбайт (т. е. кроме LongWord и Int64).
<тип> - любой допустимый тип.
Пример описания одномерных массивов
const
n =10; //будет использована в качестве индекса массива
Type //пример описания типов одномерных массивов
Mch = array [0..9] of Char; //10 элементов типа Char, счёт от 0
Mre = array [byte] of Real; //256 элементов типа Real, счёт от 0
Mint = array[3..n] of Iinteger; //8 элементов, счёт от 3 до n
Var //переменные массивы
M1 : Mch;
A : Mre;
B : Mint;
I : Byte; //будет использована для указания номера элемента массива
begin //обращение к элементам массива
M1[3] := H; //3-му элементу присвоено значение
A[15] := Sin(Pi); //15-му элементу присвоено значение функции
{Индексом элемента массива может быть константа, переменная или выражение}
i:= 3;
B[i] := B[i] +B[i+1]; //3-му элементу присвоено значение 3-го + 4-го элемента
Если элементы массива являются стандартными типами (Integer, Real, Byte,..), то определить переменную как массив можно без предварительного описания типа массива, например:
var a,b : array [1..10] of Real; //10 элементов, счет от 1
Операции с массивами
Следует различать операции с отдельными элементами массива и с массивом в целом.
С элементами массива можно производить все без исключения операции, допустимые для указанного типа.
Операции с массивами в целом возможны только для массивов одного типа. Например, операции присваивания значений одного массива другому.
type Vector = array [0..9] of Integer;
var Mv1: Vector;
Mv2: Vector; // 2 массива одного типа
…………………..
Mv1 := Mv2; {Элементы массива Mv1 получат значения элементов
массива Mv2}
В следующем примере массивы А и В описаны раздельно, компилятор относит их к разным типам, хотя и выглядят они одинаково.
var A: array [1..5] of Integer;
B: array [1..5] of Integer;
Операция A := B в этом случае ошибочная, присваивание следует выполнять поэлементно.
for i:=1 to 5 do //i счётчик, переменная целого типа
A[i] := B[i];
Над массивами не определены операции отношения. Нельзя, например, записать Mv1 = Mv2. Сравнить два массива можно только поэлементно.
Пример . Формирование массива
Дано: начальное значение X0, введённое в LabeledEdit1.Text;
приращение dX, введённое в LabeledEdit2.Text.
Требуется: разработать процедуру формирования 10-и элементов массива Mx, начиная с X0 и приращением dX.
implementation
const m=10; //кол-во элементов массива
type T_Mxy = array [1..m] of Real; //тип массива
var Mx: T_Mxy; //переменная массив
procedure Cr_Mx(Str_X, Str_d : string; Var MM: T_Mxy);
{Процедура Cr_Mx формирует массив ММ. ММ будет передан из процедуры для использования в других процедурах - поэтому ММ параметр-переменная. Str_X строка, содержащая значение Х0. Str_d - строка, содержащая значение dX.}
var i: Byte; //счётчик цикла
dX: Real; //приращение dХ
begin
MM[1] :=StrToFloat(Str_X); //Преобразование Str_X в элемент MM[1] массива
dX := StrToFloat(Str_d); //преобразование Str_d в число dX
for i :=2 to m do
MM[i]:= MM[i-1]+dX; //цикл формирования массива
end;
{Вызов процедуры формирования массива можно связать с событием нажатия кнопки. Контроль алфавита вводимых данных в тексте программы опущен.}
procedure TForm1.Button1Click(Sender: TObject);
begin
if LabeledEdit1.Text = //проверка поля X0 на пустое значение
then begin
ShowMessage('Введите X0! ');
exit //досрочное завершение процедуры
end;
if LabeledEdit2.Text='' // проверка поля dX на пустое значение
then begin
ShowMessage('Введите dX! ');
exit //досрочное завершение процедуры
end;
Cr_Mx(LabeledEdit1.Text, LabeledEdit2.Text, Mx); //массив Mx сформирован
……………………………..
end;
Пример . Формирование массива значений функции
Дано: массив Mx и процедура формирования массива Cr_Mx(Str_X, Str_d : string; Var MM: T_Mxy) (см. пример 1.);
функция FXn(X, n: Real): Real возведения X в степень n (см. работу 4), значение n введено в LabeledEdit3.Text;
метка Label3 для вывода значений массивов.
Требуется: разработать процедуру формирования массива My по значениям функции FXn(X, n ) при условии, что X принимает значения элементов массива Mx; вывести результат в виде:
i_элемент Mxi Myi
implementation //добавленный текст выделен курсивом
const m=10; //кол-во элементов массива
type T_Mxy = array [1..m] of Real; //тип массива
var Mx, My: T_Mxy; //переменные - массивы
n: Real; //показатель степени
procedure Cr_Mx(Str_X, Str_d : string; Var MM: T_Mxy);
{Процедура Cr_Mx формирует массив ММ. ММ будет передан из процедуры для использования в других процедурах - поэтому ММ параметр-переменная. Str_X строка, содержащая значение Х0. Str_d - строка, содержащая значение dX.}
var i: Byte; //счётчик цикла
dX: Real; //приращение dХ
begin
MM[1] :=StrToFloat(Str_X); //Преобразование Str_X в элемент MM[1] массива
dX := StrToFloat(Str_d); //преобразование Str_d в число dX
for i :=2 to m do
MM[i]:= MM[i-1]+dX; //цикл формирования массива
end;
procedure Cr_My(Mx: T_Mxy; var My: T_Mxy; n: real );
{Формирует массив My по значениям функции FXn(Mx[i], n). Мy будет передан из процедуры для использования в других процедурах - поэтому Мy параметр-переменная. n показатель степени.}
var i: byte; //счётчик
begin
for i:= 1 to m do
My[i]:= FXn(Mx[i], n);
end;
procedure TForm1.Button1Click(Sender: TObject);
{Проверка полей данных на пустые значения. Формирование массива Mx. Формирование массива My. Вывод №-элемента, Mx[i], My[i]}
var i: Byte;
begin
Label3.Caption:= ''; //очистка метки вывода результатов
if LabeledEdit1.Text='' //поле X0 пустое?
then begin
ShowMessage('Введите X0! ');
Exit //досрочное завершение процедуры
end;
if LabeledEdit2.Text='' //поле dX пустое?
then begin
ShowMessage('Введите dX! ');
exit //досрочное завершение процедуры
end;
if LabeledEdit3.Text<>'' //поле n не пустое?
then n:= StrToFloat( LabeledEdit3.Text) //преобразует строку в число n
else begin
ShowMessage('Введите n!');
exit //досрочное завершение процедуры
end;
Cr_Mx(LabeledEdit1.Text, LabeledEdit2.Text, Mx); //формирует массив Mx
Cr_My(Mx, My, n); //формирует массив My
For i :=1 to m do //вывод
Label3.Caption:= Label3.Caption+ IntToStr(i)+#9+ //номер элемента массива
FloatToStrF(Mx[i], ffGeneral, 5, 3)+ #9+ //Mx[i] элемент
FloatToStrF(My[i], ffGeneral, 5, 3)+ #13; //My[i] элемент
end; //конец процедуры
Недостаток рассмотренных процедур обработки массивов в том, что их можно использовать только с массивами типа T_Mxy, у которого количество элементов задано и не может быть изменено. Для обработки массива другого типа, отличающихся количеством элементов, либо нумерацией индексов, надо создавать другую процедуру.
Особенностью открытых параметров-массивов в процедурах является отсутствие указания на размерность массива в заголовке, что обеспечивает процедурам возможность работать с массивами различной размерности.
procedure Имя_Проц(Имя_Массива: array of базовый тип)
procedure Open_Vec(Vector: array of Real)
//Индексы массива в заголовке не указаны.
При работе с открытыми параметрами следует учитывать:
Для определения характеристик переданного фактического параметра-массива в теле процедуры используют следующие стандартные функции:
Low(Vec) возвращает младшее значение индекса массива, для открытых параметров-массивов всегда 0.
High(Vec) для открытого параметра-массива возвращает значение типа Word, показывая число элементов в фактическом параметре, минус 1. Для обычных массивов старшее значение индекса массива.
Пример . Открытые параметры
Объявим в процедурах формирования массива (пример 2) Cr_Mx и Cr_My параметры-массивы открытыми. Изменения, в сравнении с предыдущими вариантами, выделены курсивом. Все остальные процедуры без изменения, и здесь не приведены.
procedure Cr_Mx(Str_X, Str_d : string; Var MM: array of Real);
{Процедура формирует массив ММ. ММ - открытый параметр-переменная. Str_X - строка соответствующая Х0. Str_d - строка соответствующая dX.}
var i: Byte; //счётчик
dX: Real; //приращение dХ
begin
MM[0] :=StrToFloat(Str_X); {Преобразование строки Str_X в элемент
MM[0] массива МM. Счёт от 0}
dX := StrToFloat(Str_d); //преобразование строки Str_d в число dX
for i :=1 To High(MM) do //High(MM) старший индекс
MM[i]:= MM[i-1]+dX; //цикл формирования массива
end;
procedure Cr_My(Mx: array of Real; var My: array of Real; n: real );
{Формирует массив My по значениям функции FXn(Mx[i], n). Мy - открытый параметр-переменная. n показатель степени.}
var i: byte; //счётчик
begin
for i:= 0 to High(Mx) do //счёт от 0 до старшего индекса
My[i]:= FXn(Mx[i], n);
end;
Рассмотренные процедуры позволяют обрабатывать массивы с различным количеством элементов.
Недостаток открытых параметров-массивов в том, что количество элементов массива является константой и определено в тексте программы до её выполнения, а константу в процессе выполнения программы изменять нельзя. Динамические массивы позволяют задать массив, у которого количество элементов задаётся переменной. При объявлении таких массивов границы индексов не указывают:
var
A: array of Integer; //одномерный динамический массив
Динамические массивы не имеют установленного размера или длины. Распределение памяти и указание границ индексов по каждому измерению динамических массивов осуществляется в ходе выполнения программы путем инициации массива процедурой SetLength.
SetLength(var S; NewLength: Integer) - устанавливает длину переменной динамического массива,
где S - переменная - динамический массив;
NewLength - число элементов массива, нижняя граница индексов
динамического массива всегда равна 0.
Фактически идентификатор динамического массива ссылается на указатель, содержащий адрес первого байта памяти, выделенной для размещения массива (динамические переменные будут рассмотрены позднее). Для освобождения памяти занятой массивом достаточно присвоить идентификатору значение nil или использовать процедуру Finalize.
var
А, В: array of Integer;
………………….
begin // определяем размеры массивов
SetLength(A,10) ; //10 элементов типа Integer
SetLength(B,20) ; //20 элементов
// Используем массивы:
А := nil; //освобождаем память
Finalize(В); //освобождаем память
………………….
Пример . Динамические массивы
Предыдущую задачу формирования массивов Mx и My: решим для случая задания размерности массива в процессе выполнения программы.
Постановка задачи.
type T_Mxy = array of Real; //тип - динамический массив, размер не указан
var dX, n: Real; //приращение X, показатель степени
Mx, My: T_Mxy;
m: Integer; //кол. элементов динамического массива
procedure Cr_Mx(Str_X, Str_d : string; Var MM: array of Real);
{Текст процедуры не изменён (см. пример 3}
end;
procedure Cr_My(Mx: array of Real; var My: array of Real; n: real );
{Текст процедуры не изменён (см. пример 3}
end;
procedure TForm1.Button1Click(Sender: TObject);
{Преобразование переменных в числа выполнены}
SetLength(Mx, m); //выделение памяти массиву Mx
SetLength(My, m); //выделение памяти массиву My
Label3.Caption:= ''; //очистка метки вывода результатов
Cr_Mx(LabeledEdit1.Text, LabeledEdit2.Text, Mx); //формирует массив Mx
Cr_My(Mx, My, n); //формирует массив My
For i :=0 to m-1 do //вывод
Label3.Caption:=Label3.Caption+IntToStr(i+1)+#9+ //номер
FloatToStrF(Mx[i], ffGeneral, 5, 3)+ #9+ //Mx[i] элемент
FloatToStrF(My[i], ffGeneral, 5, 3)+ #13; //My[i] элемент
end;
procedure TForm1.FormDeactivate(Sender: TObject); //событие закрытие формы
begin
Finalize(Mx); //очистка динамической памяти
Finalize(My);
end;
Задание.
Листинг модуля с подробными комментариями.
Для каждой из пользовательских процедур дайте обоснование назначенного типа параметра (параметр-значение или параметр переменная).
Схемы алгоритмов всех нелинейных процедур.
Условия тестирования и ожидаемый результат.
Перечень ситуаций, при которых возможно аварийное завершение Вашей программы.
PAGE 68
Счётчик
1..n
Оператор
Условие
Оператор
Условие
Операторы
Схема алгоритма. Формирование массива Mx
procedure Cr_Mx(Str_Ed, Str_d : string; Var MM: T_Mxy)
Начало
Преобразование Строка-Число
MM[1] :=StrToFloat(Str_Ed)
dX := StrToFloat(Str_d);
M[i]:= MM[i-1]+dX, очередной элемент
Цикл по i, 2..m
Конец
Str_Ed поле ввода Х
Str_d поле ввода dX
m размер массива
Начало
Схема алгоритма. Формирование массива My
procedure Cr_My(Mx: T_Mxy; var My: T_Mxy; n: real )
My[i]:= FXn(Mx[i], n)
Цикл по i, 1..m
Конец
True
FXn(Mx[i], n) функция возведения в
степень n, Mx
LabeledEdit3.Text <>''
Циклический вывод: i Mx[i] My[i]
false
true
Очистка метки вывода, Label3.Caption
Exit
Схема алгоритма. Создание массивов Mx, My, вывод
procedure TForm1.Button1Click(Sender: TObject)
true
Exit
Exit
Введите dX
Введите Х
False
LabeledEdit2.Text =''
true
LabeledEdit1.Text = '', пустое поле
True
false
Конец
Начало
false
Введите n
Формирование Mx и My
Cr_Mx, Cr_My
Начало
Схема алгоритма. Формирование массива Mx
procedure Cr_Mx(Str_X, Str_d : string; Var MM: array of Real)
Преобразование Строка-Число
MM[0] :=StrToFloat(Str_X)
dX := StrToFloat(Str_d);
MM[i]:= MM[i-1]+dX
Цикл по i, 1..High(MM)
Конец
True
Начало
My[i]:= FXn(Mx[i], n)
Функция FXn возводит Mx[i]
в степень n
Цикл по I, 1..m
m количество элементов
Конец
True
Схема алгоритма. Формирование массива My по значениям Mx
procedure Cr_My(Mx: T_Mxy; var My: T_Mxy; n: real )