Оператор цикла с предусловием
На языке Pascal структура цикла с предусловием («цикл-пока») записывается следующим образом:
WHILE <условие> DO <оператор>;
WHILE, DO – зарезервированные слова (пока выполняется условие, делать);
<условие> – выражение логического типа;
<оператор> – произвольный оператор.
Если выражение <условие> имеет значение true, то выполняется <оператор>, после чего вычисление выражения <условие> и его проверка повторяются. Если <условие> имеет значение false, оператор while прекращает свою работу.
Пример 1.Найти сумму ряда с точностью , общий член которого:
Слагаемые, по модулю меньшие , не учитывать.
Program prog3_1;
conste:=0.0001;
vars,a:real; i : integer;{s – сумма, a – слагаемое}
Begin
s:=0; i:=1; a:=1/i; {задание начальных данных}
{подсчет суммы в цикле while}
whilea>=edo begin
s:=s+a; i:=i+1; a:=1/i;
end;
writeln('Ответ(while):',s:8:4); {вывод результата на экран}
End.
Перед входом в цикл задаем начальные значения исходных данных. Цикл будет выполняться, пока слагаемое будет больше заданного e. Возможна ситуация, когда заданное e больше первого слагаемого. В этом случае оператор цикла не выполнится ни разу. Значение суммы sбудет равно 0.
Оператор цикла с постусловием
Этот вид цикла отличается от предыдущего в основном тем, что проверка условия повторения тела цикла находится не перед ним, а после. Поэтому цикл с постусловием называют «циклом-до».
Формат «цикла-до» на языке Pascal:
REPEAT <тело цикла> UNTIL <условие>;
REPEAT, UNTIL – зарезервированные слова (повторять до тех пор пока не будет выполнено условие);
<тело цикла> – произвольная последовательность операторов;
<условие> – выражение логического типа.
Оператор REPEAT будет выполняться, пока <условие> ложно.
Здесь не требуется использование составного оператора, потому, что сами слова Repeat и Until являются операторными скобками.
Поскольку условие выполнения тела цикла стоит в конце, этот цикл будет выполнен хотя бы один раз, даже если условие цикла изначально истинно. Именно это отличие «цикла-до» от «цикла-пока» привело к тому, что в программировании они не подменяют друг друга, а используются для решения задач, к которым они более подходят.
Пример 2. Напишем программу для примера 1 с использованием оператора цикла с постусловием.
Program prog3_2;
conste:=0.0001;
var s, a : real; i : integer;
Begin
s:=0; i:=0; a:=0; {задание начальных данных}
repeat{подсчет суммы в цикле repeat }
s:=s+a; i:=i+1; a:=1/i;
untila<e;
writeln('Ответ(repeat):', s:8:4); {вывод результата на экран}
End.
Обратите внимание, что начальные значения i и a равны 0. Это изменение необходимо, чтобы результаты цикла while и repeat были одинаковы для всех исходных данных. В «цикле-пока» значение суммы s равно 0, если e больше первого слагаемого. В «цикле-до» первое слагаемое прибавляется к сумме до проверки условия. Поэтому если оставить i:=1; a:=1/i, то сумма будет равна 1/i, вместо 0.
В рассмотренном примере правильный результат получен как в случае использования цикла while, так и цикла repeat.
Пример 3. Дано целое число M. Требуется найти наименьшее целое неотрицательное число k, при котором y = 3k >M.
Эту задачу можно решить по следующему алгоритму: предварительно задать y=1 и k=0. Затем в цикле домножать значение y на 3, и увеличивать значение k на 1 до тех пор, пока текущее значение не окажется больше значения M.
y:=1; k:=0;
repeaty:=y*3; k:=k+1; until y >M;
Однако при y=1 будет получен неправильный результатk=1, тогда как правильное значение k=0. Это происходит из-за того, что y умножается на 3 в любом случае хотя бы раз. Оператор while позволяет избежать этой ошибки.
y:=1; k:=0;
whiley <=Mdo beginy:=y*3; k:=k+1;end;
Если M < 1, то цикл не выполнится ни разу и результат будет верным: k=0.
Оператор цикла с параметром
У этого вида цикла предусмотрено два формата:
FOR <парам. цикла>:=<нач. знач.> ТО<кон. знач.> DO <оператор>;
FOR<парам. цикла> := <нач. знач.> DOWNТО<кон. знач.> DO<оператор>;
FOR, TO, DOWNТО, DO – зарезервированные слова (для, до, выполнить).
<парам. цикла> – переменная скалярного типа;
<нач. знач.> и <кон. знач.> – выражения, определяющие начальное и конечное значение параметра;
<оператор> – произвольный оператор.
При выполнении оператора FOR вначале вычисляется выражение, задающее значение параметру цикла, затем это значение присваивается параметру цикла. После этого следует:
1) проверка условия <парам. цикла> <= <конеч. знач.> (<парам. цикла> >= <конеч. знач.>*);
если условие выполняется, то перейти к пункту 2, иначе к пункту 4;
2) выполнение оператора <оператор>;
3) изменение переменной <парам. цикла> на единицу (-1*) и переход к пункту 1;
4) завершение работы.
Пример 4.
i : integer;
оператор результат
fori:= 10to14dowrite(i:3); 10 11 12 13 14
fori:= 14to10downtowrite(i:3); 14 13 12 11 10
В данном случае параметром будет являться целочисленная переменная, которая будет изменяться на 1 (-1*) при каждой итерации цикла. Таким образом, задав начальное и конечное значения для такой переменной, можно точно установить количество выполнений тела цикла.
Пример 5.
ch : char;
оператор результат
forch:= ‘a’to‘e’dowrite(ch:2);a b c d e
for ch:=‘e’to‘a’downtowrite(ch:3);e d c b a
В первом случае параметр, который является символьной переменной, с каждой итерацией получает следующее значение в списке типа, во втором – предыдущее.
Таким образом, в отличие от первых двух видов цикла, этот цикл используется тогда, когда известно необходимое количество выполнений тела цикла.
Вообще говоря, цикл «Пока» является универсальным, то есть любая задача, требующая использования цикла, может быть решена с применением этой структуры. Циклы «До» и «С параметром» созданы для удобства программирования.
Пример 6. Найти сумму ряда k слагаемых гармонического ряда: an = 1/n (сравнить с примером 1).
Program prog3_6;
vars : real; k : integer;{s – сумма, k – количество слагаемых}
Begin
s:=0;{задание начальных данных}
fori:= 1tok do begin
s:=s + 1/i; {подсчет суммы в цикле for}
end;
writeln('Ответ(while):',s:8:4); {вывод результата на экран}
End.
Примеры использования циклов
Пример 7.
Найти р – количество трехзначных натуральных чисел, сумма цифр которых равна S (1<S<27). Операции деления (/ , div, mod) не использовать.
Program prog3_7;
uses CRT; {подключение модуля для работы с экраном}
var S, p, ns, nd, ne:word; {ns – сотни, nd – десятки, ne – единицы}
Begin
CLRSCR; {очистка экрана}
write('Введите число S ');
readln (S);
p:=0;
for ns:=1 to 9 do {цикл для задания сотен}
for nd:=0 to 9 do {цикл для задания десятков}
for ne:=1 to 9 do {цикл для задания единиц}
{проверка заданного условия}
if ns+nd+ne=S then p:=p+1;
writeln('всего р ',p:3);
End.
Пример 8.
Вычислить сумму цифр заданного натурального числа.
Program prog3_8;
USES CRT;
var i,k,f,n,s:integer;
Begin
CLRSCR;
{«цикл-пока»}
write(‘Введите число n ');
readln (n);
s:=0;
while n>0 do begin {пока n>0 :делай}
k:=n mod 10; {остаток от деления на 10}
n:=n div 10; {целая часть, от деления на 10}
s:=s+k {сумма цифр числа n}
end;
writeln (‘s=’,s:7);
{«цикл-до»}
write('Введите число n ');
readln (n);
s:=0;
repeat {начало цикла}
k:=n mod 10; {остаток от деления на 10}
n:=n div 10; {целая часть, от деления на 10}
s:=s+k {сумма цифр числа n}
until n=0; {пока условие имеет значение false выполняем}
writeln ('s=’,s:7);
End.
Пример 9. Найти сумму членов последовательности:
, (i = 0, 2, …), где |х|<1,
с точностью ε.
Если не задумываясь программировать задачу, то можно на каждом шаге цикла возводить х в степень, используя функции ln и exp, а для вычисления (‑1)i и знака числителя использовать оператор if. Однако это совершенно неэффективное решение, так как функции ln и exp сами вычисляются разложением в степенные ряды. Поэтому при решении таких задач пытаются найти связь между предыдущим и следующим членами последовательности (рекуррентное соотношение). Каждый следующий член последовательности будет получаться умножением предыдущего на найденный множитель. В нашем случае ai член связан с ai-1 соотношением:
Множитель, с помощью которого связаны два соседних члена последовательности равен .
Program prog3_9;
conste=0.0001;{значение ε }
var i:integer; a,x,s:real;
Begin
write(‘введите n и x’);
readln(n, x);{ввод начальных данных}
{цикл-пока}
s:=0; i:=1;
a:=x; {значение элемента последовательности для n=0: a0}
while a>=e do begin { пока ai>= e:делай}
s:=s+a; {добавление к сумме очередного слагаемого}
a:=-a*(2*i-1)*sqr(x)/(2*i+1);{вычисление очередного члена}
i:=i+1; {увеличение номера слагаемого}
end;
writeln ('s=’,s:7);
{цикл-до}
write(‘введите n и x’);
readln(n, x);{ввод начальных данных}
a:= 1/x; {сдвиг последовательности влево до a-1, чтобы решение давало значение s=0 для а0<e}
s:=-a; i:=0;
repeat {начало цикла}
s:=s+a; {добавление очередного слагаемого: s=0 на первом шаге цикла}
a:= -a*(2*i -1)*sqr(x)/(2*i+1); {вычисление очередного члена, начиная с а0}
i:=i+1; {увеличение номера слагаемого}
until а<e; {пока условие имеет значение false выполняем}
writeln (‘s=’,s:7);
writeln (‘s=’,s:7);
End.
Пример 10.Дано натуральное число а. Найти его разложение на простые множители. Множители вывести на экран.
Program prog3_10;
USES CRT;
var a,k,p:word;
Begin
CLRSCR;
write('Введите число а ');
readln (a); {ввод заданного числа}
K:=0;
p:=2; {наименьшее простое число}
repeat {начало цикла}
k:=0;
while a mod p=0 do begin {пока а делится на р}
a:=a div p;k:=k+1 {делим а на р и считаем степень k делителя p}
end;
if k<>0 then writeln('число',p:3,’ степень’,k:3); {вывод делителя p и степени k}
if p=2 then p:=p+1 else p:=p+2; {изменяем значение р}
until a=1; {пока условие имеет значение false выполняем}
End.
Контрольные вопросы:
1. Как программируются циклические алгоритмы с явно заданным числом повторений цикла?
2. Как программируются циклические алгоритмы с незаданным числом повторений цикла?
3. В чем отличие операторов while и repeat?
4. Можно ли изменять программным путем параметр цикла в операторе for?
5. Можно ли использовать оператор for для программирования цикла с заданным числом повторений и шагом переменной отличным от 1 и -1?
6. Как избежать «зацикливания»? Как прервать программу при зацикливании?
Лабораторная работа № 3
Задание 1. Составьте программу для решения следующей задачи, используя цикл for:
Варианты заданий:
1. Дано натуральное число п. Определить, сколько в числе нулей.
2. Найти наименьшее четырехзначное число, куб суммы цифр которого равен ему самому.
3. Найти в диапазоне [a, b] первое число, кратное c и d.
4. Найти количество отрицательных значений функции y = x2 – a*b+c*x на отрезке от х1 до х2 с шагом h. Параметры a, b, c заданы.
5. Найти наибольшее значение функции y = ax3+bx+c при заданных параметрах a, b, c, если х изменяется от х1 до х2 с шагом h.
6. Дано n-значное целое число, записать его цифры в обратном порядке.
7. Вычислить: .
8. Вычислить при данном n и действительном x
.
9. Дано натуральное число n. Вычислить произведение первых n сомножителей: .
10. Для действительного числа а и натурального числа n найти: .
11. Даны вещественное число а и натуральное число n, вычислить ((…((1+a)+a)+…+a)+a).
12. Вычислить: .
Число m ввести с клавиатуры.
13. Выдать на печать таблицу значений функции:
для с шагом .
14. Пусть ; ( ). Дано натуральное n. Найти сумму: .
15. Вычислить p по формуле Валлиса, взяв в разложении n сомножителей:
.
Задание 2. Составьте программу для решения следующей задачи, используя цикл while илиrepeat:
Варианты заданий:
1. Найти в последовательности образованной по закону
ai=аi-1-2´ ai-2, где аi-1=3, ai-2=-1, первый элемент, больший 10 и его номер в последовательности.
2. Число N содержит нечетное количество цифр. Среднюю цифру заменить на 7.
3. Найти степень числа N, у которой три последние цифры одинаковы.
4. Имеется товар в ящиках по a, b, c кг. Получить M кг товара, не вскрывая ящиков.
5. Найти первый элемент, больший K, последовательностей {x} и {y}, определяемых рекуррентными соотношениями:
xi = xi-1 +2yi-1
yi = yi-1 -2xi-1
x1 = 1, y1 = 0.
6. Дано натуральное число п. Определить, сколько в числе нулей.
7. Найти сумму ряда с точностью , общий член которого .
Слагаемые, по модулю меньше e, не учитывать.
8. Найти сумму ряда с точностью , общий член которого .
Слагаемые, по модулю меньше e, не учитывать.
9. Вычислить значение функции , для . Вычисления производить до тех пор, пока . Исходные данные – x, y, z (x, y>1) ввести с клавиатуры.
10. Вычислить с точностью :
Слагаемые, по модулю меньше e, не учитывать.
11. Для x<=1 вычислить с точностью :
Слагаемые, по модулю меньше e, не учитывать.
12. Для вычислить с точностью :
Слагаемые, по модулю меньше e, не учитывать.
13. Сумма в R рублей положена в банк. При этом прирост составляет Р% ежегодно. Через какой промежуток времени сумма достигнет М рублей. (M>R)?
14. Резервуар наполнен тлитрами водного раствора, содержащего s кг сахара. Приток воды в сосуд составляет х литров в минуту, а расход смеси из сосуда у литров. Концентрация поддерживается равномерной посредством помешивания. Каждые h минут в резервуар засыпают f кг сахара (f<s). Какую концентрацию будет иметь раствор через к минут?
4. МАССИВЫ
Данный раздел посвящен усвоению основных приемов работы со структурированными переменными типа массив, формированию представлений о различных алгоритмах обработки данных этого типа.
Структура массива в Паскале
Массивом называется конечная именованная последовательность однотипных величин. Положение каждого элемента в массиве определяется индексом. Чтобы описать массив, надо определить, какого типа его элементы и каким образом они пронумерованы (какого типа его индекс).
Паскаль допускает использование массивов произвольной размерности, но занимать они могут не более 65520 байт.
Формат описания массива:
type<имя_типа>= array[<тип_индекса>]of<тип_элемента>;
var<идентификатор, …>:<имя типа>;
Рассмотрим формат описания массивов в разделе var, без предварительного описания типа:
var<идентификатор, …>:array[<тип_индекса>]of<тип_элемента>;
Здесь array и of – ключевые слова. Индексы представляют собой выражения любого порядкового типа. Тип индекса определяет границы изменений значений индекса. Элементами массива могут быть данные любого типа, включая структурированные.
Примеры описания типа:
typemas =array[1 .. 10]ofreal;
Color =array[byte]ofmas;
Menu = (F1, F2, F3, F4, F5);
Active =array[Menu]ofboolean;
В первом примере описан тип массива из вещественных элементов, которые нумеруются от 1 до 10. Во втором – элементами массива являются массивы типа mas, а нумеруются они в пределах, допустимых для типа byte, то е от 0 до 255. В третьем в качестве индекса использовано имя перечисляемого типа данных, а сами элементы могут принимать значения true или false.
При обращении к элементу массива индексы указываются в квадратных скобках после имени массива. Над элементами массива допустимы все действия, определенные для данного типа. Единственным действием, которое возможно произвести с массивом целиком – присваивание и сравнение. Но для этого массивы должны быть описаны через имя типа, либо в одном списке раздела var.
Пример 1.
type d=array[1..m]of integer;
var d1,d2:d; d3,d4:array[1..m]of integer; d5:array[1..m]of integer;
d1:=d2; d3:=d4; {возможные действия}
d1:=d3; d5:=d1; d5:=d3;{ошибка, так как d1,d3, d5 имеют разные типы}
Одномерные массивы
Линейный массив является линейной таблицей, в которой для точного указания на элемент данных достаточно знания только одного индекса.
Пример 2.
Var
s, bb :array[-20..20]ofreal;
n :array['A'..'Z']ofInteger;
r :array[boolean]ofword;
Примеры обращения к элементам массива: s[-5], bb[i], n[‘h’], r[false].
Пример 3. Написать программу, которая вводит с клавиатуры 20 целых чисел, а затем распечатывает их в обратном порядке.
ProgramProg4_1;
var A : array[1..20] Of integer;
i : integer;
Begin
for i:=1 to 20 do{организуем цикл с параметром i }
readln(A[i]); {вводим A[i] с клавиатуры }
{выводим массив в обратном порядке}
for i:=20 downto1 dowrite(A[i]:5);
End.
Пример 4. Заполнить массив значениям квадратов индексов элементов.
ProgramProg4_2;
Const
n=50; {константа n задает количество элементов массива}
Var
A : array [1..n] Of integer;
i : integer;
Begin
for i:=1 to n do
A[i]:=i*i; {присваиваем элементам массива значениям квадратов индексов }
for i:=1 to n do
write(A[i]:5);
End.
Пример 5. Программа находит сумму всех элементов и количество отрицательных элементов в целочисленном массиве из 10 элементов.
ProgramProg4_3;
const n=10; {константа n будет содержать количество
элементов массива}
var A : array [1 .. n] of integer;
i, sum, num : integer;
Begin
writeln('Введите ', n, ' элементов массива'):
for i:=1 to n do read(A[i]); {вводим массив}
sum:=0; num:=0; {задаем начальные значения sum и num}
for i := 1 to n do begin sum:=sum+A[i];
if A[i]<0 then inc(num); {подсчет числа
отрицательных элементов}
end;
writeln('Сумма элементов: ', sum);
writeln('Отрицательных элементов: ', num);
End.
Пример 6. В линейной целочисленной таблице найти индекс первого элемента, являющегося двузначным числом.
ProgramProg4_4;
const n=50; {константа n будет содержать количество
элементов массива}
var a : array [1..n] of integer;
i:integer; { индекс искомого элемента}
Begin
randomize;
{формируем a[i] генератором случайных чисел}
for i:=1 to n do a[i]:=random(1000)-500;
i:=1;
while (i<=n) and not((a[i]>9) and (a[i]<100)) doinc(i); {увеличиваем i, если не находим элемент, удовлетворяющий условию задачи }
{если есть такой элемент, то выводим его индекс}
if i<= n then writeln('индекс = ', i);
End.
Двумерные массивы
В Паскале можно использовать массивы произвольной размерности, однако практика программирования показывает, что массивы размерности больше двух используются редко. Если речь идет о двумерных (в общем случае – многомерных) массивах, то в описаниях должны быть заданы диапазоны изменения всех индексов. Это можно делать по-разному.
Пример 7.
typedim=array[1..10]ofword;
vardim1: array[1..6, 1..10]ofword;
vardim1: array[1..6]of array[1..10]ofword;
vardim1: array[1..6]of dim;
Обращаться к элементам получившегося массива можно: dim1[4,8] или dim1[4][8].
Пример 8. Подсчитать в целочисленной двумерной таблице
a[1:7, 1:10] количество положительных элементов.
ProgramProg4_5;
var a : array [1..20,1..20] of integer;
m,n,i,j k:integer; { m – количество строк, n – количество
столбцов массива, k – количество положительных элементов}
Begin
writeln('Введите m,n');
readln(m,n);
writeln('Введите массив');
for i:=1 to m do
for i:=1 to n do read(a[I,j]);{вводим массив}
k:=0;
for i:=1 to m do
for j := 1 to n do
if a[i,j]>0 then
k:=k+1;
writeln(‘k=’,k);
End.
Пример 9. Дан двумерный массив A(m,n). Найти максимальный элемент массива и номер содержащего его столбца. Исходную матрицу вывести на экран.
ProgramProg4_6;
const m=6,n=5; {константа m – количество строк,
n – количество столбцов массива}
var a:array [1..m,1..n] of real;
max: real; {max – значение максимального элемента }
i, j, num:integer; {num – номер столбца с максимальным
элементом}
Begin
writeln('Введите массив');
for i:=1 to m do
for j:=1 to n do read(a[i,j]); {вводим массив}
{поиск максимального элемента в цикле}
max:=a[1,1];
for i := 1 to m
for j := 1 to n do
if a[i,j]>max then
begin max:=a[i,j];num:=j;end;
writeln(‘макс=’,max:8:3,’в столбце’, num);
End.
Контрольные вопросы:
1. Что понимается под массивом?
2. Каковы возможные способы описания массивов (одномерных и многомерных)?
3. В каких случаях целесообразно описывать двумерный массив с помощью одномерных?
4. Какие типы допустимы для описания индексов массивов?
5. Какие типы могут использоваться в качестве базовых для описания массивов?
6. Как осуществляется ввод и вывод массивов?
Лабораторная работа № 4
Задание 1. Составьте программу для решения следующей задачи обработки одномерных массивов произвольной длины. Выведите на монитор исходные данные и результат.
Варианты заданий:
1. Заданы два одномерных массива различных размеров. Объединить их в один массив, включив второй массив между K-м и (K+1)-м элементами первого (K задано),
2. Найти среднее арифметическое заданного массива размером M. Преобразовать исходный массив, вычитая из каждого элемента среднее значение.
3. Найти количество перемен знака в массиве из N чисел. Нулевые элементы заменить абсолютным значением предыдущего. Если первый элемент нулевой, то заменить его числом F.
4. Задан массив из K чисел, составить программу замены нулей полусуммой следующего и предыдущего чисел. На место последнего или первого нуля ставить соответственно предыдущее или последующее число.
5. Найти минимальный элемент среди положительных чисел и максимальный среди отрицательных.
6. Удалить из массива целых чисел размером P элементов все четные числа, стоящие на нечетных местах, сдвинув оставшиеся в начало массива.
7. Удалить из массива вещественных чисел все максимальные элементы, сдвинув оставшиеся влево на освободившиеся места, справа записать нули.
8. Найти среднее арифметическое элементов, расположенных между первым четным и последним нечетным числом, встречающимся в целочисленной линейной таблице.
9. В заданный массив целых чисел из N элементов вставить элемент, равный M после последнего минимума.
10. Задан массив целых чисел из T элементов. Найти первую пару соседних противоположных чисел (их сумма равна 0).
11. В заданном массиве вещественных чисел найти наибольшую длину цепочки стоящих рядом знакочередующихся элементов.
12. Исключить из заданной целочисленной таблицы из M элементов числа k-го десятка, на их место сдвинуть элементы влево.
13. Найти количество различных элементов в заданном массиве вещественных чисел.
14. В целочисленном одномерном массиве длины K найти число, повторяющееся наибольшее количество раз. Если таковых несколько, то сохранить их в массиве.
15. Даны два одномерных массива различных размеров. Упорядочить их по убыванию, получить из них один упорядоченный массив. Примечание: объединять массивы и упорядочивать элементы необходимо одновременно.
Задание 2. Составьте программу для решения следующей задачи обработки двумерных массивов произвольной длины. Выведите на монитор исходные данные и результат.
Варианты заданий:
1. Элементы столбца матрицы с максимальным по модулю элементом в k-ой строке заменить на число X.
2. Переставить i-ую и j-ую строки матрицы.
3. Упорядочить m-ую строку по невозрастанию элементов. Вывести исходный массив и полученный вектор.
4. Из заданной матрицы удалить k-ую строку и l-ый столбец.
5. Из матрицы B(m,n) сформировать матрицу C(m,n), каждый элемент которой получается путем вычитания из соответствующего элемента матрицы B первого элемента данной строки.
6. Задана матрица размером m ´ n. Просуммировать элементы, расположенные на главной и побочных (соседних с главной) диагоналях. Результат получить в виде вектора.
7. Вычислить количество положительных элементов, расположенных в нечетных строках матрицы, и найти среди них минимальный.
8. В данной действительной матрице найти суммы элементов строк, в которых расположен элемент с наименьшим значением.
9. Найти строки матрицы с наибольшей и наименьшей суммой элементов. Сформировать из этих строк вектор.
10. Задан двумерный массив размерности m ´ n. Дополнить его строкой и столбцом, в которых записать суммы элементов соответствующих строк и столбцов исходного массива. В элементе (m+1,n+1) должна храниться сумма всех элементов первоначального массива.
11. Целочисленная двумерная матрица разделяется главной диагональю на два треугольника. Из одинаковых чисел среди элементов верхнего и нижнего треугольников сформировать вектор.
12. В заданной двумерной матрице замените строки, содержащие максимальный элемент, на соответствующие строки единичной матрицы.
13. Заданы натуральное четырехзначное число и двумерный массив, элементами которого являются натуральные четырехзначные числа. Определить, имеется ли в таблице число с обратным порядком расположения цифр по отношению к данному. Найти его индексы.
14. Задана вещественная матрица размерности m ´ n. Переставляя строки и столбцы добейтесь перемещения минимального элемента матрицы в верхний левый угол (если минимум встречается несколько раз, то переставить самый близкий элемент к правому нижнему углу).
15. Дан символьный двумерный массив. Найти номер последнего по порядку столбца, в котором содержится наибольшее количество различных символов.
ПРОЦЕДУРЫ И ФУНКЦИИ
Цель: обучение модульной организации алгоритма, формирование умения создания программ с подпрограммами, усвоение понятий формальных и фактических параметров и способов их передачи между основной программой и подпрограммами, выработка навыков построения рекурсивных алгоритмов.
При решении сложных объемных задач часто целесообразно разбивать их на более простые. В этом случае говорят о вспомогательных алгоритмах или подпрограммах. Использование подпрограмм позволяет сделать основную программу более наглядной, понятной, уменьшить вероятность ошибок и облегчить процесс отладки программы, а в случае, когда одна и та же последовательность команд встречается в программе несколько раз, сократить объем программы.
Подпрограмма – это поименованная последовательность операторов, которую можно многократно вызывать для исполнения в любом месте программы. При обращении к подпрограмме в нее передаются исходные данные, а после выполнения операторов подпрограммы передаются в основную программу результаты расчетов. В языке Паскаль существует два вида подпрограмм, определяемых программистом: процедуры и функции, которые отличаются способом использования в программе. Процедуры и функции, используемые в программе, должны быть соответствующим образом описаны в разделе описаний до первого их упоминания. Процедуры и функции, входящие в программу, могут содержать свои подпрограммы и вызвать процедуры и функции более низкого уровня и т.д.
Процедуры
Процедурой в Паскале называется именованная последовательность инструкций, реализующая некоторое действие. В нужное место программы процедуру вызывают с помощью оператора вызова. После выполнения процедуры программа перейдет к выполнению оператора, следующего за оператором вызова.
Формат описания процедуры:
Procedure<Имя процедуры>(<форм. параметры>);
<Раздел описаний>
Begin
<Тело процедуры>
End;
Формальные параметры – перечень имен для обозначения исходных данных и результатов работы процедуры, используемых для описания процедуры, с указанием их типов.
Раздел описаний может иметь такие же подразделы, как и раздел описаний основной программы. Однако все описанные здесь объекты доступны лишь в этой процедуре. Они локальны так же, как и имена формальных параметров. Объекты, описанные ранее в разделе описаний основной программы и не переопределенные в процедуре, называются глобальными для этой подпрограммы и доступны для использования.
Формат оператора вызова:
<имя процедуры> (<фактические параметры>);
Фактические параметры – данные, с которыми выполняется процедура. Между формальными и фактическими параметрами должно быть соответствие по количеству, типу и порядку следования.
Процедуры могут быть без параметров, например, Procedure Pl1;. При описании процедур без параметров используются глобальные переменные.
Параметры процедуры
Существует два способа передачи фактических параметров в подпрограмму: по значению и по ссылке. Соответственно параметры называются параметрами-значениями и параметрами-переменными.
В первом случае значение переменной – фактического параметра при вызове подпрограммы присваивается локальной переменной, являющейся формальным параметром подпрограммы. Изменение локальной переменной никак не отражается на соответствующей глобальной. В качестве фактических параметров может служить любое выражение соответствующего типа.
Передача параметров по ссылке отличается тем, что при обращении к подпрограмме имя формального параметра будет указывать на ту же область памяти, что и имя соответствующего фактического параметра. При описании подпрограммы перед именем параметра-переменной ставится служебное слово Var. В этом случае изменения выполняются в ячейках памяти фактических параметров. Поэтому в качестве фактических параметров можно использовать только имена переменных.
Примеры использования процедур
Пример 1. Написать программу сложения полиномов.
Рассмотрим упрощенный случай, когда оба многочлена имеют одинаковые степени.
ProgramProg5_1;
constm =30;
typepol = array[0..m] of real;
var f, g, h: pol; k : word; {полиномам-слагаемым и } {полиному-сумме соответствуют массивы f, g и h}
{ Процедура сложения коэффициентов полиномов}
Proceduresum(n:integer; var m,h,s:pol);{параметр n задает размерность массива <=30}
vari:integer;
Begin
fori:=1 ton dos[i]:=m[i]+h[i];
End;
Begin
Randomize;
for k:=0 to m do begin
f[k]:=(Random-0.5)*50;{коэффициенты полиномов }
g[k]:=(Random-0.5)*50;{задаются случайными числами}
end;
sum(m,f,g,h);
{вывод коэффициентов полиномов в три столбца}
writeln(' f g h ');
writeln(‘---------------------‘);
for k := 0 to m do
writeln (f[k]:6:3, g[k]:7:3, h[k]:7:3);
End.
В процедуру передаем размерность массива, чтобы программа могла складывать полиномы различных степеней, меньших 30. Исходные массивы передаем по ссылке, в этом случае в стеке не создается копия исходных массивов, что улучшает быстродействие и экономит память.
Пример 2. Напишите процедуру нахождения линейной комбинации (k1*a+k2*b) векторов. Найдите какую-либо линейную комбинацию трех векторов размерности 7.
ProgramProg5_2;
type Tarray = array[1..100] of real;{предположим, что наибольшее число элементов в массиве не превышает 100}var a,b,c,s: Tarray; n,i,k1,k2,k3:integer; {процедура ввода массива размерности n}Procedure vvod_data(n:integer; var m:Tarray;);var i:integer;Begin
writeln('Введите ',n,' чисел');for i:=1 to n doread(m[i]); {вводим массив}
End;
{процедура вычисления линейной комбинации массивов размерности n с коэффициентами k и l}Proceduresumm(n:integer;k,l:real; var m,h,s:TArray);
var i:integer;Begin
for i:=1 to n do s[i]:=k*m[i]+l*h[i];End;Begin
write('Введите размерность массива N= '); readln(n); vvod_Data(n,a); {ввода массива a}vvod_Data(n,b); {ввода массива b}vvod_Data(n,c); {ввода массива c}summ(n,k1,k2,a,b,s); {вычисление линейной комбинации массивов a, b с коэффициентами k1 и k2}summ(n,1,k3,s,c,s); {вычисления линейной комбинации}{полученного массива s с коэффициентом 1}{и массива с с коэффициентом k3}writeln('результат= ',s);End.
Пример 3. Вставить элемент х до и элемент у после каждого элемента таблицы, меньшего некоторого числа р. Вставку х и у выполнять в процедуре.
ProgramProg5_3;
const n=12; x=1;y=-1;{n – размерность исходного массива}
typemas =array[1..3*n]of integer;
var