70331

Программирование на алгоритмическом языке Паскаль

Книга

Информатика, кибернетика и программирование

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

Русский

2014-10-19

644.5 KB

3 чел.

PAGE  2

Турбо Паскаль   

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РФ

МОСКОВСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ

ТЕХНОЛОГИЙ И УПРАВЛЕНИЯ

имени К.Г.Разумовского

Кафедра «Информационные технологии»

УЧЕБНО-ПРАКТИЧЕСКОЕ

ПОСОБИЕ

С ЛАБОРАТОРНЫМ ПРАКТИКУМОМ

Раздел: «Основы алгоритмизации

и программирования»

Программирование на

алгоритмическом языке Паскаль

Попов А.А.


Программирование на алгоритмическом языке Турбо Паскаль

с лабораторным практикумом

1. ВВЕДЕНИЕ

Алгоритмические языки предоставляют возможность человеку управлять действиями ЭВМ. Существует множество таких языков, среди которых очень популярным является Турбо Паскаль (далее просто Паскаль).

Символы. В Паскале разрешены следующие основные символы: 1. Буквы латинского и русского языков (кириллица используется только в константах). 2. Цифры. 3. Символы:  + – * / = > < . , ( ) [ ] ‘ ; ^ : и другие.

Операции. Арифметические: +, , * (умножение), / (вещественное деление). Операции отношений: =,  >, <, >= (больше или равно),<= (меньше или равно), <> (не равно). Операции возведения в произвольную степень в Паскале нет.

Кроме перечисленных, имеются еще две арифметические операции над целыми числами:

div  – целочисленное деление (дробь отбрасывается, например 14 div 3=4),

mod целочисленный остаток от деления (пример 14 mod 3=2),

Переменные снабжаются именами, которые могут содержать латинские буквы, цифры и знаки подчеркивания, но начинаться имя должно с буквы. Программист выбирает имена произвольно, но таким образом, чтобы они указывали на смысл переменной. За каждой переменной компьютер закрепляет одну ячейку памяти. Большие и маленькие буквы в именах воспринимаются компьютером одинаково, т.е. буквы W и w обозначают одну и ту же переменную. Примеры имен: Х, y, A24, VES_Netto, MAXIMUM.

Типы переменных. Всем переменным в программе предварительно должны быть указаны типы. Вот важнейшие.

числовой целый   Integer (диапазон от –32768 до +32767)

числовой целый длинный  Longint (диапазон от –2147483648 до +2147483647)

числовой вещественный  Real (диапазон от 2,9Е-39 до 1,7Е+38)

символ   Char (один символ)

строка символов  String (до 255 символов)

логический   Boolean (имеет два значения true – истина, false – ложь).

Задание типа производится оператором VAR. Например: VAR  a,d: INTEGER;   x: REAL;  d: STRING;.

В разделе констант можно сразу задать и тип и значение переменной CONST  b: INTEGER=5; s:STRING=’поле’. Здесь переменным придаются и типы и значения.

Выражения используются для отображения формул и записываются в строку. Вычисления в них реализуются слева направо в общепринятой последовательности: 1. вычисление функций, 2. умножение-деление, 3. сложение-вычитание. Порядок действий может быть изменен скобками. Следующие два примера иллюстрируют правила построения выражений (слева в рамке формулы в обычной записи, справа выражения на Паскале):

  

     XC+2.5/(6*K)                    F4/(B*3)+(C*B/(T–5))*8.4

Функции реализуют стандартные действия. Функции всегда содержат скобки (кроме Pi). Ниже показаны важнейшие:

Функция

Назначение

Тип аргумента

Тип результата

Примеры

abs(x)

модуль х

целый/вещественный

как у аргумента

abs(–6)=6

sin(x)

синус угла х (аргумент в радианах)

вещественный

вещественный

cos(x)

косинус угла х (аргумент в радианах)

arctan(x)

арктангенс х (результат в радианах)

sqrt(x)

квадратный корень из х (х≥0)

целый/вещественный

как у аргумента

sqr(x)

квадрат х

exp(x)

ex

вещественный

вещественный

ln(x)

логарифм натуральный х (x>0)

int(x)

целая часть числа х

int(1.2)=int(1.9)=1

frac(x)

дробная часть числа х

frac(-2.5)=-0.5

odd(x)

выявление нечетности х

целый

логический

odd(3)=true

pi

число π=3.14159...

вещественный

trunc(x)

отбрасывает дробную часть х

вещественный

целый

trunc(3.7)=3

round(x)

округляет вещественное х до целого

вещественный

целый

round(3.7)=4

Преобразование вещественного типа в целый осуществляется функциями round и trunc. Преобразование в вещественный тип может быть осуществлено простым присваиванием вида вещественная переменная:=целочисленная переменная (например a:=d). Такое преобразование называется неявным.

2. ОПЕРАТОРЫ ЯЗЫКА

Оператор – основная единица программы и имеет множество разновидностей. Рассмотрим самые простые.

Оператор присваивания. Общий вид оператора присваивания:

переменная:=выражение

Такая запись означает, что выражение, стоящее справа, вычисляется и его результат присваивается переменной, стоящей слева. Примеры операторов:    Z:=2,     А:=3.5+EXP(8),     S:=X*4+Y/2.

Присваивание не является равенством в обычном смысле. Здесь справа и слева от знака равно можно указывать одну и туже переменную. Например, допустимо: М:=М+2, X:=X/3. Эти выражения следует понимать так, что новое содержимое ячейки М будет равно старому, увеличенному на два, и новое Х будет равно старому, деленноу на три. Например, если ранее было М=3 и Х=12, то после вычислений получим М=3+2=5 и Х=12/3=4.

Оператор вывода. Для анализа результатов вычислений необходимо вывести их на внешний носитель – бумагу или экран дисплея. Для этой цели используется оператор.

 WRITE(список_выводимых_переменных)

 WRITELN(список_выводимых_переменных)

Например, оператор: WRITELN(a, m)   читается так – “Печатать переменные А, М”.

Различие двух форм оператора заключается в том, что вторая разновидность оператора после вывода данных переводит курсор на новую строку (line). Оператор writeln может использоваться и без аргументов (и без скобок). Тогда при выводе будет формироваться только пустая строка. В оператор могут включаться не только переменные, но и константы и выражения. Например, если Х=12, а Y=100, то применение оператора WRITE('X=', x, 'Y=', y, 'СУММА=', x+y)  даст следующий результат: X=12 Y=100 СУММА=112.

С помощью оператора можно указать не только что будет выведено, но и как, т.е. отформатировать вывод. После имени вещественной переменной можно (через двоеточие) задать два числа. Первое из них задаст общую длину вывода числа, второе – размер дробной части. После имени целочисленной переменной нужно задать только одно число. Например, оператор WRITE(k:6, z:8:2) при выводе отведет для целочисленной переменной K 6 позиций, а для вещественной переменной Z – 8, из которых 2 под дробную часть. Лишние позиции, отведенные под целую часть, заместятся пробелами.

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

 READLN(список_вводимых_переменных)

Встречая такой оператор, компьютер останавливается и ждет вашего ввода. Число вводимых данных по количеству и типу должно соответствовать списку переменных. Если список переменных содержит более одной переменной, действия пользователя зависят от типов, вводимых данных. Числовые значения разделяются нажатием Enter или пробелом, а в конце Enter. Если вводятся данные типа char – символы набирать следует подряд. Данные типа string разделяются пробелом. Оператор может и не иметь аргументов вовсе (readln()). Тогда все, что вы можете сделать, это нажать Enter.

Пример: READLN(r,l). Дословно, оператор интерпретируется так: “Читать в память компьютера, введенные с клавиатуры, переменные R и L”. Пусть в нашей программе R=5 и L=8.4. Тогда пользователь должен ввести 5 и 8.4 через пробел или Enter.

С тем, чтобы пользователь понимал, чего от него хочет компьютер, а не видел лишь черный экран с курсором, удобно прежде оператора ввода разместить оператор вывода с необходимым текстом-подсказкой.

Оператор завершения используется для принудительного завершения программы/процедуры в любом ее месте.

 EXIT

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

 READKEY

Оператор очистки освобождает экран и устанавливает курсор в левый верхний угол.

 CLRSCR

Этот оператор и оператор readkey находятся в библиотеке CRT Паскаля и, чтобы ими воспользоваться, следует ее подключить оператором USES CRT. 

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

Операторные скобки используются, чтобы выделить некоторую группу операторов как единое целое.

 BEGIN...END

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

Запись операторов. Оператор может занимать любое количество строк и для переноса на другую строку не нужно никаких символов переноса. Все операторы Паскаля завершаются знаком “точка с запятой”. Однако после оператора begin и перед оператором end точку с запятой можно не ставить.

Структура программы на Паскале имеет две части: описательную (пункты

1,2,3) и вычислительную и состоит из следующих элементов (см. рисунок справа):

1. Задается имя программы (необязательно).

2. Присоединяются библиотеки Паскаля.

3. Описываются все участвующие метки, переменные, константы, типы и т.п.

4. Оператором Begin открывается вычислительная часть.

5. Внутри блока помещаются операторы собственно программы.

6. Оператором End (с точкой) завершается вся программа.

Теперь напишем простую программу вычисления площади круга S произвольного радиуса R по известной формуле S=πR2. Программу назовем KRUG. Переменные S и R обозначим как вещественные, поскольку они могут иметь дробную часть. Ввод радиуса осуществляется оператором readln(r). Чтобы пользователь понимал, что именно он должен ввести, прежде оператором write(‘радиус=’) на экран выводится слово “радиус=”. В конце программы видим оператор readkey. Он нужен для удобства отладки. Встречая его, компьютер ожидает от пользователя нажатия любой клавиши. В это время он может без спешки осмотреть результаты счета. Если этого не сделать Паскаль сразу же вернет нас в окно редактирования и тогда окно выдачи придется вызывать клавишами Alt+F5, что неудобно. Остальное очевидно. Замечание. В текстах следующих примеров для компактности мы не будем больше вносить команду очистки экрана, оператор задержки readkey, и, в большинстве случаев, операторы-подсказки ввода, однако студент должен это делать.

3. ОРГАНИЗАЦИЯ ВЕТВЛЕНИЙ

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

Условный оператор позволяет выполнять некоторые действия в зависимости от заданных условий.

 IF логическое условие THEN оператор1 ELSE оператор2

Здесь, если условие истинно, выполняется оператор1, иначе оператор2. Например, оператор

IF a>b THEN WRITELN ('А больше В')  ELSE WRITELN ('А не больше В');

выводит словесное сообщение о фактическом соотношении переменных А и В.

Оператор может использоваться и в усеченной форме без опции ELSE.

Другой пример. На практике иногда приходится выяснять кратность числа (например Х) некоторому другому числу (Y). Это можно сделать с помощью следующего выражения (оба числа должны быть целого типа)

IF x MOD y =0 THEN WRITELN ('X кратно Y') ELSE WRITELN ('X не кратно Y')

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

IF x>0

  THEN BEGIN y:=SQRT(x); WRITELN('корень=', y) END

  ELSE WRITELN('число отрицательно')

Внутрь оператора if могут быть вложены другие if. Например, пусть в последовательности чисел a,b,c требуется вывести первое по порядку положительное число. Если таковых не оказалось, печатать “Все числа отрицательны”. Программа справа.

Оператор безусловного перехода. Оператор вида:

 GOTO метка оператора

вынуждает программу выполнять не следующий по порядку оператор, а оператор с указанной меткой. Например, оператор GOTO m читается как “Идти к оператору с меткой mи передает ему управление. Метки должны быть предварительно объявлены оператором label в разделе объявлений программы (в нашем случае label m). Меткам можно давать произвольные символьные или числовые имена, важно только, чтобы все метки были разными, т.е. никогда не совпадали в пределах программы. В операторе, на который происходит ссылка, метка ставится перед ним и отделяется двоеточием.

Очень распространенной задачей является программирование процессов с несколькими исходами – ветвящихся процессов. Здесь удобно (по крайней мере, на первом этапе) сначала построить блок-схему, дающую наглядное графическое представление алгоритма. В блок-схеме отдельные операции или их группы помещаются в прямоугольные блоки. Операции анализа отображаются ромбами. Обозначение других операций будет рассмотрено позже. Блок-схемы обрамляют блоки НАЧАЛО и КОНЕЦ. Мы будем изображать последние только в случае, если возможно разночтение.

Задача 3-1. Для произвольного аргумента

Х вычислить значение кусочно-ломаной

функции Y(X) (рис.3-1а).

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

по-разному. Два таких решения приведены в program p3_1 (рис. 3-1б и 3-1в).

Второй вариант работает быстрее поскольку при выполнении условия, следующие условия не проверяются.

4. ЛОГИЧЕСКИЕ ФУНКЦИИ

Функция одного аргумента НЕ (NOT) истинна тогда, когда ложен ее аргумент (значение функции обратно аргументу). Поведение функции полностью описывает таблица. Например, следующие два оператора полностью идентичны

if x<10 then y=5   if not (x>=10) then y=5

аргумент

функция

НЕ

1-й

аргумент

2-й

аргумент

функция

И

функция

ИЛИ

Ложь

Истина

Ложь

Ложь

Ложь

Ложь

Истина

Ложь

Ложь

Истина

Ложь

Истина

Истина

Ложь

Ложь

Истина

Истина

Истина

Истина

Истина

Функций двух аргументов. Функция И (AND) истинна когда истинны все ее аргументы. Функция ИЛИ (OR) истинна, если истинен хотя бы один из аргументов. Если нет скобок, функции вычисляются в следующей последовательности: НЕ,И,ИЛИ. Словам Истина и Ложь в Паскале соответствуют значения True и False.

Логические операции имеют приоритет перед операциями отношения, поэтому, если таких условий несколько, последние берутся в скобки. В качестве примера снова рассмотрим задачу 3-2. Решение будет очень компактным (вспомогательные операторы опущены):

readln(a,b,c);

if (a+b>=c) and (b*b>a) then writeln('верно') else writeln('неверно');

Пример. Для чисел А,В,С выяснить, правда ли что первое число самое большое, а последнее – самое маленькое.

if (a>b) and (a>c) and (c<a) and (c<b) then writeln('верно') else writeln('неверно');

Еще. Верно ли, что среди чисел есть отрицательные.

if (a<0) or (b<0) or (c<0) then ...

Еще. Верно ли, что среди чисел ровно одно меньше нуля.

if (a<0) and (b>0) and (c>0) or (a>0) and (b<1) and (c>0) or (a>0) and (b>0) and (c<0)  then ...

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

Задание. Имеются числа a,b,c. Вывести их в порядке возрастания.

Задание. Выяснить, правда ли, что среди чисел a,b,c,d имеется хотя бы одно отрицательное и одно положительное.

Задание. Выяснить, правда ли, что среди a,b,c,d имеется в точности одно отрицательное и одно нулевое числа.

Оператор выбора. При необходимости сделать выбор из многих альтернатив конструкция с вложением if становится очень громоздкой. В этом случае полезным может оказаться оператор case. Здесь выражение может быть целого или символьного типа. Если его значение равно одной из констант, выполняется соответствующий оператор. Если ни одна из констант не подходит, выполняется оператор, следующий после слова else (если есть). Любая из констант может быть диапазоном (через две точки) и/или множеством констант (через запятую). Любой оператор может быть блоком и содержать свои операторы case и if.

Задача 4-1. Пусть требуется по числу прожитых лет Т отнести человека к какой-то возрастной группе. Решение очевидно, но нуждается в одном пояснении. Поскольку женщины и мужчины уходят на пенсию в разное время (55 и 60 лет), кроме возраста нужно учитывать и пол Р.

Задача 4-2. Положим, введен какой-то знак в переменную S и его нужно отнести к соответствующей группе. Следует сказать, что латинские символы в символьной таблице ПК находятся не вместе. Подряд идут буквы с А по Z, затем идут не буквы, затем буквы с а по z. В виду этого пришлось указать два диапазона констант ('A'..'Z','a'..'z'). Символы русского алфавита состоят из еще большего числа диапазонов (см. раздел ‘Символьные данные’).

Задание. Написать программу, в которой вводятся два числа-операнда Х и Y и знак операции Z (+,–,/,*). Вычислить результат S в зависимости от знака. Предусмотреть реакции на возможный неверный знак операции, а также на ввод Y=0 при делении.

5. ОРГАНИЗАЦИЯ ЦИКЛОВ

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

Итерационные циклы. В случае, если число циклов, необходимых для решения задачи, заранее неизвестно, такие циклы называются итерационными. Рассмотрим ряд примеров.

Задача 5-1. Пусть для некоторого множества чисел Х нужно вычислить и отпечатать функцию Х/2. Ввод и вычисления следует прекратить после обнаружения первого Х, равного нулю. Очевидна следующая блок-схема (рис.5-1а). Блоков ввода, вычисления, печати и анализа столько, сколько чисел в последовательности до первого нуля. Чисел может быть очень много и подобный подход, конечно, неприемлем, не говоря уже о том, что количество их заранее неизвестно. Такие программы строятся по-иному. Обрабатывающая часть программы записывается только раз, но охватывается петлей возврата (рис.5-1б). Тогда одни и те же операторы будут выполняться многократно до тех пор, пока Х#0. Для реализации цикла здесь понадобилась метка (m).

Задание. Наберите программу Р3. Затем улучшите ее: введите необходимые подсказки, отформатируйте вывод, сделайте очистку экрана, введите подсчет количества точек Х, для которых был вычислен Y. Выдайте сообщение “Х=0” по завершении программы.

Задача 5-2. Пусть для аргумента Х, находящегося в диапазоне 3÷9, требуется вычислить и напечатать значение функции Y=(X–6)2, где Х изменяется с шагом 2 (рис. 5-2а, 5-2б). Справа от текста программы сделаны выкладки по проверке решения. В каждой строке вручную вычисляется значение соответствующей переменной. Проверка выполняются сверху-вниз, слева-направо по ходу исполнения программы. Стрелки показывают связи между циклами. Видим, что заданная последовательность изменения Х (3,5,7,...) наблюдается и последнее значение Y вычисляется для Х=9. При следующем приращении Х оно становится равным 11 и пятый цикл не выполняется, поскольку Х>9. Программа завершается. Следует отметить, что нет никакого технически простого способа проверки правильности написанных программ. Для этой цели программисту приходится вручную по тексту программы рассчитывать значения переменных и сличать их с желаемыми (известными из условия). Конечно, проверка выполняется не для всей задачи, а только для небольшого числа (например, 3-х) начальных циклов и при этом тщательно анализируется значение условия выхода из цикла (здесь оператор IF).

Задание. Вычислите функцию в обратном порядке. Подсчитайте среднее арифметическое всех Х и Y.

Арифметические циклы. Если число повторений известно заранее – такие циклы называются арифметическими.

Задача 5-3. Пусть в условиях предыдущей задачи не известно предельное значение аргумента, но зато задано количество точек аргумента – 4. Поскольку в данном случае не задано последнее значение Х, признак окончания циклов придется формировать самим. Для этого вводится переменная, которая фиксирует число уже выполненных циклов, т.е. счетчик циклов (назовем ее I). В исходном состоянии (рис.5-3) берем его равным 1. После выполнения очередного цикла счетчик получает приращение на единицу (I=I+1). В начале каждого цикла в операторе IF делается проверка на достижение счетчиком последнего разрешенного значения (у нас 4). Если I<=4 программа продолжает вычисление функции, если нет (I>4) – счет прекращается. Рядом с программой приведены выкладки по ее проверке. Как видим, результат проверки совпал с результатом, полученным ранее. По очевидным причинам счетчик циклов I должен быть целочисленного типа.

Задание. Напишите программу вычисления функции в обратном порядке. Сделайте число точек не константой (4), а переменной N, вводимой оператором read. При прогоне программы задайте N=100. Поскольку весь результат теперь не умещается на экране, организуйте паузу при выдаче каждых 20-ти строк (понадобится операция mod и readkey).

program P5_3;

проверка

label d;

var x,y:real; i:integer;

begin

1

цикл

2

цикл

3

цикл

4

цикл

x:=3;  i:=1;

d: if i>4 then exit;

   y:=sqr(x–6);

   writeln(x,y);

   x:=x+2;

   i:=i+1;

goto d;

end.

x=3,  i=1

i=1<4

y=9

3, 9

x=5

i=2

2<4

y=1

5, 1

x=7

i=3

3<4

y=1

7, 1

x=9

i=4

4=4

y=9

9, 9

x=11

i=5

5>4

конец

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

Оператор цикла for:

 FOR переменная цикла := начальное значение ТО конечное значение DO оператор

реализует приращение счетчика циклов на единицу в заданных пределах и контроль его значения. Цикл завершается в момент, когда переменная цикла становится больше конечного значения цикла. Например, оператор:

FOR a = 3 TO 7 DO WRITELN(a);

дословно интерпретируется следующим образом: “Оператор WRITELN после слова DO будет повторяться столько раз, сколько нужно, чтобы переменная А, изменяясь с шагом 1 от значения равного 3, достигла 7”. Т.е.: A=3; 4; 5; 6; 7 и цикл будет выполнен 5 раз. Если после слова DO поместить конструкцию begin...end, цикл может содержать неограниченное число операторов, например

FOR i = 1 TO n DO BEGIN WRITELN(i); READLN(x) END;

Имеется форма оператора, работающего на убывание (шаг равен –1).

 FOR переменная цикла := начальное значение DOWNТО конечное значение DO оператор

В качестве параметров оператора цикла разрешены и выражения, например, FOR c=b+2 TO 4*k DO ...

Важно: все параметры-переменные в операторе FOR должны быть целого типа.

Задачи на накопление. В практике очень распространены задачи на накопление, т.е. на нахождение сумм и произведений последовательности переменных. Такие задачи могут встречаться как в формулировке итерационных, так и арифметических циклов.

Задача 5-4. Пусть требуется найти сумму N произвольных чисел Х. В программе P5_4 сумма накапливается в переменной S с помощью оператора S=S+X. Начальное значение суммы берется равным нулю (S=0).

Задание. Переделайте программу таким образом, чтобы она вычисляла еще среднее арифметическое и произведение.

Числовые ряды. Типичной циклической задачей на накопление является вычисление числовых рядов.

Задача 5-5. Пусть требуется найти сумму S для N членов геометрической прогрессии (справа). Здесь каждый следующий член прогрессии Аi равен предыдущему Ai-1, умноженному на два. Если учесть введенные обозначения, можно записать так называемые рекуррентные формулы:

Si =  Si-1 + Ai,     где Sо=0  Или, как принято S=S+A,        S=0

Ai = 2Ai-1       A1=3.  в программировании: A=2A,       A=3.

Действие оператора FOR применительно к задаче отражено блок-схемой на рис. 5-5. Сам оператор FOR помещается в фигуру “прямоугольник в ромбе”, которая имеет два выхода. Выход ДА соответствует случаю, когда переменная цикла меньше или равна своему предельному значению (здесь I<=N) – цикл продолжает выполняться. Выход НЕТ – случаю превышения переменной этой границы – цикл завершается.

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

Задание. Напишите программу вычисления произведения N элементов числового ряда.

     Z1A1    Z2A2     Z3A3    Z4A4

P= –3    ·    5     ·  –7   ·   9  · – ... =  ПАi.    Здесь справедливы формулы:

  

      P1       P2           P3          P4

Для формирования изменяющегося знака вводим специальную переменную Z и задаем ей первоначальное значение, совпадающее со знаком первого сомножимого (–1). Далее знак будет изменяться на противоположный при каждом умножении на минус 1 (Z=–Z).

program P5_6;

label t;

проверка для n=5 (х=3, –2, 1, –3, 2)

var i,n,kp:integer; x,s,p:real;

begin

1

цикл

2

цикл

3

цикл

4

цикл

5

цикл

readln (n);

kp:=0;  s:=0;  p:=1;

for i:=1 to n do begin

    readln(x);

    if x=0 then goto t;

    if x<0 then s:=s+x;

    if x>0 then begin

          kp:=kp+1;  

        p:=p*x    end;

end;

writeln(‘0 нет’);

t: writeln(s,p,kp);

end.

n=5

i=1<5

x=3

kp=1

p=3

2<5

x=–2

s=–2

3<5

x=1

kp=2

p=3

4<5

x=–3

s=–5

5=5

x=2

kp=3

p=6

6>5

0 нет

–5,6,3

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

Задача 5-6. Для N произвольных чисел Х вычислить и отпечатать:

1) сумму отрицательных чисел S,  2) количество положительных чисел КР, 3) произведение положительных чисел Р.

Все вычисления производить до появления первого нуля в последовательности. Если ноль не встретился, кроме S, KP и Р, печатать сообщение Нулей нет. Блок-схема алгоритма приведена на рис. 5-6. Проверка в программе сделана для N=5 и Х=3, –2, 1, –3, 2. В результате: S=–5, P=6, KP=3.

Задание. Программа имеет один дефект. Произведение положительных элементов может оказаться равным 1, как в случае, если оно действительно таким получилось, так и если положительных чисел не было совсем (ведь исходное значение произведения =1). Исправьте программу.

Оператор цикла с предусловием имеет вид

WHILE условие DO оператор

Такая конструкция позволяет легко организовывать итерационные циклы (циклы с заранее неизвестным числом повторений). Оператор, входящий в тело цикла выполняются до тех пор, пока истинно условие. Для примера решим задачу 4 – вычислять и печатать Y=Х2 до обнаружения первого Х=0. Программа приведена ниже.

readln(x);     {Y=Х2}

while x<>0 do begin

   writeln(х, х*x);

   readln(x)

end;

С помощью этого оператора гораздо удобнее программировать задачу 5-2 (program P5_2).

Оператор цикла с постусловием:

 REPEAT оператор UNTIL условие

Оператор, в цикле выполняется до тех пор, пока истинно условие. В отличие от оператора WHILE здесь цикл будет выполнен хотя бы один раз. Структуру с постусловием удобно применять в случае, если цикл необходимо выполнить хотя бы раз независимо от значения условия или, если само условие формируется в цикле и не может быть оценено до входа в цикл.

Выход из цикла после выполнения всех его циклов называется естественным. Принудительный выход для всех видов циклов может быть выполнен специальным оператор выхода

 BREAK

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

 СONTINUE

Действие указанных операторов (применительно к циклу FOR) иллюстрирует рисунок выше.

Задание. Написать программу в которой вводятся два операнда Х и Y и знак операции (+,–,/,*). Вычислить результат Z в зависимости от знака. Предусмотреть реакции на возможный неверный знак операции, а также на ввод Y=0 при делении. Организовать возможность многократных вычислений без перезагрузки программа (т.е. построить цикл). В качестве символа прекращения вычислений принять ‘0’.

Функциональные ряды. При работе с компьютером возникает впечатление его огромной интеллектуальной силы. На самом деле это совсем не так. Собственно процессор умеет (правда очень быстро) выполнять только четыре арифметических действия и логические операции, т.е. располагает возможностями ученика 1-го класса. Откуда же вся его математическая мощь. Ответ простой – от программистов. Разработчики компиляторов языков (в частности Паскаля) побеспокоились о том, чтобы в нем присутствовали многие математические функции. Когда мы используем выражение exp(x) мы на самом деле вызываем подпрограмму вычисления ex, написанную для нас неизвестным автором из фирмы Borland. Однако мы можем и сами это сделать. Существует методы, позволяющие вычислять функции, используя лишь небогатые возможности процессора. Так из математики хорошо известны функциональные ряды Тейлора (здесь аргумент включен в члены ряда). Хотя такие ряды бесконечны, нам нет необходимости (и возможности) вычислять их целиком. Значения элементов ряда быстро убывают и мы можем прекратить вычисления в тот момент, когда очередной член станет меньше заданной погрешности ε.

Задача 5-7. Вычислить с заданной погрешностью функцию ex для произвольного значения Х. Ряд Тейлора для нее выглядит следующим образом.

ex ≈1+x+x2/2!+ x3/3!+ x4/4!+...

Отсюда можно записать аналитические зависимости (здесь у – искомая функция, r – элемент ряда, i – номер члена разложения):

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

y=x11!/2!–x32!/3!+ x43!/4!– x54!/5!+...

Сложные циклы. Этот термин означает вложенность одного цикла в другой.

Задача 5-8. Вычислить значения функции Y=X2+Z для 0≤X≤4 и 0≤Z≤10 с шагом 1. В этой функции два аргумента, т.е. она является не плоской кривой, а криволинейной поверхностью. Решение здесь очень простое. Строятся два цикла – внешний (по Х) и внутренний (по Y). Поскольку аргументы и функция целочисленные и шаг равен 1, можно использовать оператор for. В данном случае безразлично, какой параметр поместить снаружи, а какой внутри. Здесь на одно изменение переменной Х произойдет 11 изменений z.

В следующих заданиях условия целочисленности аргумента и/или шаг=1 не соблюдаются, и для организации циклов придется использовать оператор while.

Задание. Вычислить функции Y=X2+Z для 0≤X≤4 с шагом 1 и 1≤Z≤10 с шагом 2.

Задание. Вычислить функции Y=X2+Z для 0≤X≤4 с шагом 0,5 и 1≤Z≤10 с шагом 2.

6. МАССИВЫ

Как правило, данные для вычислений задаются в упорядоченной форме – в виде последовательности ряда (вектора) чисел или в виде таблицы (матрицы) чисел. Такие совокупности данных называются массивами. Например, вектор А длиной К чисел и матрица В из N строк и M столбцов (всего из NŸM элементов) выглядят следующим (справа) образом. Построение программ, оперирующих с элементами массивов – важнейшая часть техники программирования.

Цифры при имени массива, указывающие порядковый номер элемента, называются индексами. Элементы массивов Аi и Bij обозначаются как А[I] и B[I,J]. К массиву в целом обратиться нельзя. Обработка массива означает последовательную обработку отдельных его элементов.

Оператор описания массивов. Если предполагается работа с массивами, предварительно следует “известить” об этом компьютер в разделе описаний (VAR) программы. Для одномерного массива это оператор вида

имя_массива: ARRAY [диапазон] OF тип_массива

Например,        VAR x,z: ARRAY [1..8] OF REAL;   y: ARRAY [5..10] OF INTEGER;  b: ARRAY [1..4, 1..5] OF INTEGER;

program P6_1;

var i,n,m,k: integer;

      c: array [1..10] of integer;

begin

write('n='); readln(n);

for i:=1 to n do begin

  write('i=',i:2,' c='); readln(c[i]);

end;

n=4

Пр

оверка

m:=c[1];  k:=1;

for i:=2 to n do

  if m<c[i] then begin

      m:=c[i];  k:=i    end;

writeln('m=',m:2,' n=',k:1);

end.

m=5, k=1

i=2

5>2

i=3

5<7 m=7,k=3

i=4

7>4

i=5

7, 3

Здесь первый оператор описывает массивы X и Z из 8-ти элементов (с номерами от 1 до 8) вещественного типа. Второй – массив Y из 5-ти элементов (с номерами от 5 до 10) целочисленного типа, третий – двумерный массив B из четырех строк и пяти столбцов.

VAR i,j: INTEGER;

{ввод вектора Х с подсказкой}

FOR i:=1 TO 8 DO BEGIN  

   WRITE(‘x[',i,']='); READLN(x[i]) END;                                     

{ввод матрицы В с подсказкой}

FOR i:=1 TO 4 DO

   FOR j:=1 TO 5 DO BEGIN  

         WRITE('b[',i,j,']=');  READLN(b[i,j]);

   END;

{построчный вывод матрицы B}

FOR i:=1 TO 4 DO BEGIN

      FOR j:=1 TO 5 DO  WRITE('b[',i,j,']=',b[i,j]:4:1,' ');

      WRITELN  {вывод пустой строки}

END;

Первоочередной задачей при работе с массивами является ввод-вывод данных. Ввод организуется с помощью циклов, как показано ниже. Сначала осуществляется ввод в вектор X. На экране мы увидим, например, подсказку вида х[2]=, после чего можно ввести значение этого элемента. Аналогичную (b[2,4]=) подсказку увидим для матрицы В размерностью 4 строки на 5 столбцов. Ввод осуществляется с помощью двух циклов, один из которых вложен в другой. В наружном цикле изменяется первый индекс I элемента матрицы В, во внутреннем – второй индекс J. Второй индекс J изменяется быстрее, чем первый (на одно изменение I индекс J изменяется 5 раз). Это означает, что ввод элементов матрицы будет производиться в следующей последовательности: B[1,1],B[1,2],...B[1,5];  B[2,1],B[2,2],...B[2,5] ;...; B[4,1],B[4,2],...B[4,5], т.е. по строкам. Аналогичным образом осуществляется и вывод, но вместо оператора READLN используется оператор WRITELN. В примере производится вывод данных из матрицы В. Если позволяет ширина экрана, удобно выводить одну строку матрицы на одной строке монитора. Оператор WRITE( 'b[',i,j,']=',b[i,j]:4:1,' ') выводит данные, например, в виде b[2,3]=25.3. Поскольку оператор WRITE не переводит строку вывода, принудительный переход на новую строку осуществляется пустым оператором WRITELN после того, как строка была полностью выведена.

Начальные значения скалярным переменным и элементам массива (в особенности при отладке) можно задать в разделе констант (начинается со слова const). Например:

CONST   z:ARRAY [1..3] OF INTEGER=(4,5,2);

x: INTEGER=5;

r:ARRAY [1..3,1..2] OF INTEGER=((1,2),(3,4),(5,6));

Здесь вектору Z присваиваются значения: z[1]=4, z[2] =5, z[3]=2, переменной х: 5, а прямоугольной матрице R: r[1,1]=1, r[1,2]=2, r[2,1]=3, r[2,2]=4, r[3,1]=5, r[3,2]=6.

Задача 6-1. В векторе С предельной размерности 30 элементов найти максимальный по значению элемент и его номер в С по порядку. В программе сделана проверка для N=4 и C=[5,2,7,4] в ее обрабатывающей части. Здесь переменная М запоминает значение максимального элемента, а К – номер этого элемента в векторе С. Первоначально в качестве такого элемента берется самый первый.

Задача 6-2. Определим значения вкладов в банке на конец года. Положим, имеется N счетов вкладчиков. Для всех них известны значения остатков на счете в конце каждого квартала. Следует определить и напечатать значения всех вкладов на конец года с учетом известного процента роста вклада. Все суммы считаем целочисленными (копейки игнорируем).

Данные о вкладах хранятся в массиве Х из N строк и пяти столбцов. Первые четыре элемента каждой i-ой строки (Х[i,1], Х[i,2], Х[i,3], Х[i,4]), хранят остатки вклада на конец каждого из четырех кварталов года. В последний, пятый элемент строки X[i,5] следует занести вычисленную величину вклада на конец года, который равен остатку вклада на конец последнего квартала Х[i,4], плюс установленный процент от среднего значения вклада Y=(Х[i,1]+ Х[i,2]+ Х[i,3]+Х[i,4])/4 за год. Положим, определено, что на вклад до 5000 предусмотрен процент роста – 10%, на вклад до 10000 – 15%, на вклад свыше 10000 – 20%. Иными словами установлены коэффициенты роста 1.1, 1.15 и 1.2 соответственно. Кроме перечисленного, следует найти сумму всех вкладов в банке S и среднее значение вклада, приходящееся на одного вкладчика (S/N). 

Задание. В векторе Х найти элемент, максимально близкий к некоторому Y и его номер.

Задание. В векторе Х сдвинуть по кольцу его содержимое на 1 клетку. На 2 клетки. На К клеток. Подсказка. Здесь понадобится вспомогательный массив Y, куда и будем заносить уже сдвинутые данные.

Задание. Пусть имеется таблица, содержащая сведения о работниках бригады: Имя, Отработано дней, Зарплата. Известна также сумма, которую заработала бригада S. Рассчитать зарплату для каждого работника. Усложним задачу. Пусть зарплата увеличивается на 10% тем, кто отработал больше 20-ти дней (при прежнем S). Во всех случаях сумма всех зарплат работников должна быть в точности равна S.

Задание. Запрограммировать процесс выбора в детской считалке. Пусть нужно выбрать случайным образом дежурного из группы в M человек. Дети становятся в круг и “считаются” по следующему правилу. Из круга по часовой стрелке удаляется каждый третий (шаг выбора N) участник, начиная с номера 1. В конце останется только один – дежурный. Для (см. рисунок) примера M=8, N=3. Тогда последовательно из круга выйдут номера 1,4,7,3,8,6. Наконец останутся только номера 2 и 5 и счет продолжается уже между ними 252. Таким образом, “повезло” номеру 5. Задания решить двумя способами, указанными ниже. В программе вывести номера всех выбывающих элементов и номер дежурного.

Алгоритм 1.Создается массив Х длиной в несколько раз больше чем M. Обозначим его размерность MM (в программе задайте ММ=30). Первые его M элементов заполняются последовательными числами от 1 до M. Остальные элементы от M+1 до MM остаются пока пустыми (=0). Строится FOR-цикл перебора всех элементов X. В нем, если номер элемента I минус 1 кратен N, этот номер (он подчеркнут) печатается и человек выбывает. Если нет, элемент переносится в правый конец занятой части массива Х (в первую свободную клетку). Если встретился элемент =0, значит произошла обработка всех чисел и процесс прекращается. На рисунке показана динамика изменения массива Х. Первоначально в нем заняты только клетки с 1 по 8. Цифры 1,4,7 печатаются, а остальное (2,3,5,6,8) последовательно переносится в свободную область Х, из которой печатаются цифры 3 и 8 и т.д. пока не будут выведены все цифры. После 22-ой ячейки остаются еще MM-22 пустых клеток. Их просматривать не нужно и для этого в цикле должен быть предусмотрен выход при X[i]=0.

Х

1

2

3

4

5

6

7

8

2

3

5

6

8

2

5

6

2

5

2

5

5

5

дальше нули

1

4

7

3

8

6

2

5

выбывание

i:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

Алгоритм 2. Возможен и другой алгоритм, заключающийся в том, что, как и в жизни, мы будем ходить по кругу из элементов массива Х размерности M. Каждый раз, когда человек выбывает, мы печатаем его номер и (чтобы не забыть, что он выбыл) заменяем содержимое соответствующей ячейки на 0. Здесь введем переменные: I=1 – номер каждого элемента в круге, J=1 – номер только не удаленного элемента (клетки, содержащие 0 игнорируются), L=0 число уже отобранных клеток.

1). Организуем хождение по кругу. Строим WHILE-цикл в котором переменная I меняется от 1 до M (т.е 1..M, 1..M, и т.д.). В цикле I=I+1 всегда и J=J+1 – только для непустых клеток.

2). Внутри цикла, каждый раз, когда J становится кратным K, ячейка Х(J) печатается и очищается Х[I]=0, L=L+1.

3). Вычисления прекращаются при L=M.

Сортировки в массиве. Сортировка данных является очень распространенной задачей и для нее имеется несколько методов.

Задача 6-3. В векторе X расположить элементы в порядке убывания их значений. Алгоритм реализуется при помощи двух вложенных циклов. В наружном цикле последовательно перебираются числа x(i) массива и во внутреннем сравниваются со всеми оставшимися числами x(j) справа от данного. Если выясняется, что какое-то из x(i) меньше сравниваемого, они меняются местами – большее число становится на место меньшего. В программе для наглядности в качестве элементов массива взяты их номера i. Если вектор имеет длину четыре (N=4), будет выполнена следующая последовательность перестановок чисел: 1,2,3,4:

при i=1 – 2,1,3,4;  3,1,2,4;  4,1,2,3;  при i=2 – 4,2,1,3;  4,3,1,2;  при i=3 – 4,3,2,1.

Здесь для обмена значений элементов x[i]↔x[j] вводится специальная “транзитная” переменная М для временного хранения данных. Действительно, если использовать только операторы x[i]:=x[j]; x[j]:=x[i] мы получим неверный результат. Хотя х[i] и примет значение х[j], оператор  x[j]:=x[i] ничего не изменит, ведь х[i] теперь равен х[j]. С тем, чтобы не потерять исходное значение х[i], оно запоминается в переменной М.

Задание. Сортировка выбором. Рассмотренный алгоритм очень прост для программирования, но содержит лишние действия. Очевидно, нет необходимости делать обмен элементов всякий раз, когда встретился больший элемент. На самом деле это нужно выполнить только единожды для максимального элемента. Напишите такую программу.

Задание. Сортировка обменом. Метод заключается в анализе соседних элементов массива. Если х[i]<х[i+1] элементы меняются местами. По достижении конца массива в нижней клетке окажется самое маленькое значение. Затем процесс повторяется, но уже без последнего элемента и т.д. Такой просмотр вектора нужно выполнить N раз. Однако его можно сократить, если зафиксировать факт прекращения обменов.

Задание. Пусть имеется таблица работников цеха со столбцами: Имя, Бригада, Отработано дней, Зарплата. Отсортировать любым методом таблицу по возрастанию значений столбца “Отработано дней”.

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

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

Задача 6-4. Заполнить двумерный массив A(N,N) элементами натурального ряда (т.е. числами 1,2,3, и т.д.), начиная с нижнего правого угла в направлении, показанном пунктиром на рис. 6-4а. Чтобы выявить необходимые законы перемещения по матрице, в ее клетках показаны индексы элементов. Способов решения таких такого рода задач может быть несколько. Заметим, что в зависимости от того, с какой стороны матрицы мы находимся, нам необходимо совершать следующие движения:

если вы находитесь у правой стороны матрицы, типовое движение это вверх на одну клетку и вниз-влево по диагонали до нижней границы;

если у нижней границы, то влево на одну клетку и вверх-вправо по диагонали до правой границы;

у верхней границы – влево на одну клетку и вниз-влево до левой границы;

 у левой границы – вверх на одну клетку и вверх-вправо до правой границы.

В любом случае движение прекращается при достижении клетки A(1,1). Результат заполнения массива А показан на рис. 6-4б. Программа приведена ниже. Здесь ST – номер текущей строки (первоначально N, поскольку движение начинается с последней ячейки массива A(N,N)), KL – номер текущей колонки (первоначально N), K – растущее значение натурального ряда (первоначально 1). Самый внешний цикл (while k<n*n) ограничивает все действия достижением растущим значением натурального ряда K значения N*N, поскольку именно столько клеток имеется в квадратной матрице размерности N. Внутри цикла организованы четыре разные группы операций в зависимости от того, какое из четырех типовых элементарных действий (см. выше) выполняется. Определяет тип действия оператор if/else if, в котором выясняется, где именно вы находитесь. Внутри каждого IF организован цикл while, в котором осуществляются необходимые перемещения в матрице в соответствии с одним из четырех алгоритмов. По завершении всех действий, т.е. после достижения последней клетки (в нашем случае A(1,1)), выполняется последовательная печать строк матрицы A с заполненными клетками.

program P6-4;

uses crt;

var n,i,j,st,kl,k:integer;

a:array [1..10,1..10] of integer;

begin;

clrscr;

write(‘укажите размерность матрицы (до 10)’); readln(n);

st:=n; kl:=n; k:=1;   {текущие строка и колонка, элементы натурального ряда}

a[st,kl]:=k;    {начальному элементу a(n,n) присваивается 1}

while k<n*n do begin   {конец вычислений по достижении последнего элемента массива}

if (kl=n) and (st>1) then begin st:=st-1; k:=k+1; a[st,kl]:=k; {правая сторона – 1 клетка вверх}

       while (st<n) and (kl>0) do begin st:=st+1; kl:=kl-1; k:=k+1; a[st,kl]:=k end; {далее вниз-влево

end

else if (kl>1) and (st=n) then begin kl:=kl-1; k:=k+1; a[st,kl]:=k; {нижняя сторона – 1 клетка влево, }

       while (st>1) and (kl<n) do begin st:=st-1; kl:=kl+1; k:=k+1; a[st,kl]:=k end; {далее вверх-вправо}

end

else if (kl>1) and (st=1) then begin kl:=kl-1; k:=k+1; a[st,kl]:=k; {верхняя сторона – 1 клетка влево, }

       while (st<n) and (kl>1) do begin st:=st+1; kl:=kl-1; k:=k+1; a[st,kl]:=k end; {далее вниз-влево}

end

else if(kl=1) and (st>1) then begin st:=st-1; k:=k+1; a[st,kl]:=k; {левая сторона – 1 клетка вверх, }

       while (st>1) and (kl>0) do begin st:=st-1; kl:=kl+1; k:=k+1; a[st,kl]:=k end; {далее вверх-вправо}

end;

end;

writeln('вывод результата');

for i:=1 to n do begin   for j:=1 to n do write(a[i,j]:4);  writeln;  end;

end.

Задание. Поиск в отсортированном массиве. Очевидно, что найти нужное значение Х можно сплошным перебором данных. Однако в худшем случае (если искомое значение находится внизу или его нет вовсе) нам придется просмотреть все элементы массива. Имеется гораздо более быстрый алгоритм, называемый бинарным поиском. Массив делится пополам и Х сравнивается со средним элементом. Если Х оказался больше, пополам делится нижняя часть, если нет – верхняя и т.д. Напишите программу поиска.

7. СИМВОЛЬНЫЕ ДАННЫЕ

Паскаль позволяет обрабатывать не только числовые, но и символьные данные, которые бывают двух типов. Символы описываются в описательной части программы атрибутом CHAR и хранят один знак. Строки это цепочки символов и описываются атрибутом STRING. Например, var ST: char; SM: string[32]; SS: string. Здесь ST – одиночный символ, SM – строка не более чем из 32 символов. Если количество символов не указано, строке присваивается емкость в 255 символа. В программе и символы и строки должны заключаться в апострофы, например:  ST:=‘a’;  SM:=‘экзамен’;. Над символами и строками с помощью приведенных в таблице функций производятся различные операции.

Функция

Назначение

concat (строка1,строка2)

Соединяет строки строка1 и строка2 в одну (пример: concat(‘а’,’б’)=’аб’)

copy(строка, позиция,

     количество)

Копирует из строки, начиная с заданной позиции количество символов

(пример: copy(‘программа’,4,5)=’грамм’)

delete(строка,

     количество,позиция)

Удаляет из строки количество символов, начиная с заданной позиции

(пример: delete(‘программа’,4,4)=’прома’)

insert(строка1,строка2,

     позиция)

Вставляет строку1в строку2, начиная с заданной позиции

(пример: insert(‘сколько стоит’,’это ’,9)= ‘сколько это стоит’)

length(строка)

Определяет длину строки (пример: length(‘саша’)=4)

pos(строка1,строка2)

Отыскивает в строке2 первое вхождение строки1 и определяет номер

позиции, с которой она начинается (пример: pos(‘саша’,’а’)=2)

upcase(символ)

Преобразует символ латинского алфавита в заглавный

str(число,

     формат,строка)

Преобразует число типа integer или real в строку по заданному (если есть) формату

(примеры: str(5,x) – результат х=’5’,  str(18.3:5:2,y) – результат y=’18.30’)

val(строка,

     число,признак)

Преобразует строку в целое или вещественное число, если оно прошло успешно, признак =0

(пример: val(’12.4’,x,k) – получим x=12.4, k=0)

ord(символ)

Преобразует символ в целое число – код символа в ASCII-таблице (пример: ord(Я)=159)

chr(число)

Преобразует число в символ из ASCII-таблицы с соответствующим кодом (пример: chr(159)=’Я’)

Над символьными данными определена операция ‘+’ (аналогичная concat) сцепления. Пример: ‘студент ’+’Петров’= ’студент Петров’.

Задача 7-1. В символьной строке Х=‘Петров Саша’ поменять местами имя и фамилию и поместить результат в Y. Решение потребует трех действий: 1). Нахождение позиции пробела n=7, 2). Остаток фразы от пробела (т.е. ‘Саша’) поместить в Y. 3).Дополнить Y пробелом и начальным фрагментом фразы Х до пробела. Для наглядности процесс реализован в трех операторах. Но можно записать его и в один y:=copy(x,pos(' ',x)+1,length(x))+' '+copy(x,1,pos(' ',x)-1);

коды

символы

0..32

управляющие

65..90

A..Z

97..122

a..z

128..159

А..Я (кроме Ё)

160..175

а..п (кроме ё)

224..239

р..я

240,241

Ё,ё

Задача 7-2. В символьной строке Х подсчитать количество K слов. Считаем, что число слов равно числу пробелов +1. Первый вариант программы P7_2 имеет недостаток. Если перед первым словом предложения или после последнего имеются пробелы, или внутри фразы встречается более одного пробела разом, число найденных слов окажется больше фактического. Исправим программу с учетом этих обстоятельств. Во втором варианте добавлен просмотр начала фразы до первого не пробела (j – номер первого значащего символа). Затем просматривается остаток фразы, где подсчитываются только одиночные пробелы (после пробела в i-ой позиции не должен стоять другой пробел). Дополните программу выдачей по отдельности всех слов предложения и их (справа) длин.

Представление символьных данных. Каждому символу ПК сопоставлен код (целое число от 0 до 255) из ASCII-таблицы. Первые 128 символов включают цифры, знаки, латинские символы. Из них символы с кодами 0..31 являются служебными (возврат каретки, перевод строки и т.д.). Латинские буквы A..Z имеют коды 65..90, a..z – 97..122. Следующие 128 позиций заняты символами псевдографики и буквами национального алфавита. В кириллице буквы A..Я имеют коды 128..159, a..п – 160..175, р..я – 224..239, буквы Ё – 240, ё – 241. Замечаем, что коды заглавных и строчных букв a..п различаются на 32, а букв р..я – на 80. Очевидно, что на клавиатуре нет всех 256 знаков. Тем не менее, они могут быть отражены в программе с помощью своего кода в форме: #код. Например, оператор write(#65,#177,#201,#205,#187); выведет строку: “A▒╔═╗”. Символы, отсутствующие на клавиатуре, можно найти в справочнике, а можно и вывести вместе с их кодами на экран с помощью операторов: for i:=0 to 255 do write(chr(i),i:3,' ');. Отметим, что коды от 0 до 31 являются управляющими и, хотя многие из них имеют экранное отображение, использовать эти символы для непосредственного вывода нельзя.

Символьные данные можно сравнивать между собой. При этом более короткая строка дополняется символами с кодом 0 до размеров более длинной строки. Далее последовательно слева направо коды символов сравниваются попарно из обеих строк (чей код больше – тот символ больше). Например: ‘а’<’б’; ‘а’=’а’; ’а’>’А’ (заглавные буквы имеют меньший код); ‘ВАЛЯ’<’ВАСЯ’ (расхождение в третьем символе, где ‘Л’<’C’); ‘ЯША’>’ПETP’ (буква Я больше П).

Задача 7-3. В строке S содержатся русские и латинские символы (заглавные и строчные), цифры и знаки препинания. Преобразовать все символы S в заглавные. Результат занести в D. В программе Х – строка размером в один символ, куда заносятся поочередно все символы из S для преобразования. В результате получим D='абвxyz123ABC'. Преобразование здесь осуществляет оператор вида X:=chr(ord(x[1])-32). Здесь сначала выясняется код ord(x[1]) текущего символа, из него вычитается 32 (т.е. вычисляется код соответствующей заглавной буквы), и, наконец, этот код снова преобразуется в символ.

Задания.

1. В символьной строке Х удалить лишние (начальные, конечные и сдвоенные) пробелы.

2. В Х подсчитать число вхождений слова ‘его’.

3. В Х поменять порядок символов на обратный.

4. В Х напечатать самое длинное слово.

5. В Х подсчитать число вхождений всех встречающихся знаков.

6. В Х подсчитать число вхождений произвольного символа.

7. В Х в каждом слове поменять порядок символов на обратный.

8. В Х расположить слова в порядке увеличения их длины.

9. Имеется строка Х длиной ≤N, предназначенная для вывода. Выровнять X к правой границе так, чтобы строка занимала все N позиций. Выравнивание производить за счет равномерного увеличения числа пробелов между словами.

10. Зашифровать строку Х, заменив каждый символ, на символ, следующий за данным по алфавиту (буква А заменяется на Б и т.д., буква Я заменяется на А). Расшифровать полученный текст.

11. Написать программу формирования числа (до 1000 руб.) в сумму прописью (например, 103=‘сто три рубля’).

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

13. В строка Х содержит любые русские и латинские символы (как заглавные, так и строчные), цифры и знаки препинания. Преобразовать все символы Х в строчные. Результат занести в Y.

14. Пусть имеется таблица работников бригады со столбцами: Имя, Отработано дней, Зарплата. Отсортировать любым методом таблицу по алфавиту. Для упрощения будем считать, что имена не превышают 8-ми символов, содержат только заглавные буквы и не имеют буквы Ё (эта буква в кодовой таблице русских символов находится не на месте).

15. Отсортировать таблицу по алфавиту, где для имен допускаются любые буквы русского алфавита, включая Ё и ё. Сложность здесь заключается как раз в этих буквах. Их коды 240 и 241, т.е. самые большие среди русских букв, в виду чего сравнивать слова придется не целиком, а побуквенно. В случае, если встретилась буква Ё и ё, в программе они должны считаться большими букв Е/е и меньшими Ж/ж.

16. Написать программу, которая из заданной даты (в диапазоне 1900..2100) формирует следующую. Исходная дата задается в форме текстовой строки вида ‘дд.мм.гггг’, например ’06.04.2002’. Подсказка: признаком високосного года является кратность года числу 4. Исключением являются года с двумя нулями на конце, число сотен в которых не кратно 4 (например 1800, 1900, 2100).

17. Написать программу, которая от заданной даты (диапазон 1900..2100) находит новую, отстоящую от данной на М месяцев. Если в новом месяце такой даты нет, берется последний день нового месяца.

18. Написать программу, которая от заданной даты (1900..2100), находит новую, отстоящую от данной на Х дней.

8. ЗАПИСИ

Массивы определяют однородную совокупность данных. На практике часто требуется объединять в один объект данные разных типов. Так для хранения сведений о месячной выработке работников бригады понадобятся следующие сведения: Табельный номер, Имя, Дневной тариф, число отработанных Дней. Ясно, что табельный номер должен быть целого типа, имя – строкового, тариф и дни – вещественного. Мы можем объединить эту совокупность данных (они называются полями) в объект, называемый запись (record). Дадим ему, например имя Vr (от слова выработка). Первоначально удобно описать тип-запись как тип данных конструкцией, изображенной слева. Позже с помощью оператора Var можно описать уже конкретные записи данного типа.

type vr=record  {объявление типа записи}

  tab: integer;    {табель}   

  im: string[4];  {имя}

  tarif, dn: real      

end;

var x:vr; y:array [1..5] of vr;

9. ФАЙЛЫ

Информация в компьютере хранится в файлах (обычно на диске). Файловая система состоит из двух уровней: физического файла и логического файла. Физический файл – это собственно файл данных на диске, порт, принтер, любое устройство. Логический файл – файловая переменная (типа String), описанная в программе в разделе переменных. В зависимости от способа объявления формируется один из следующих типов файлов:

1. Типизированные файлы. Состоят из данных одного, объявленного типа.

Объявление файла: [имя]: file of [тип]; Примеры: A: file of string[80];   F1: file of char;   F2: file of real;

2. Текстовые файлы. Состоят из символов. Объявление текстового файла:   [имя]: text;.   Пример: f3: text;

В типизированных файлах информация хранится в двоичном виде, а в текстовых – в естественном. Элемент файла – запись (не путать с понятием record). Обычно, это строка файла.

Подлинное имя дискового файла используется только чтобы связать его с внутренним именем в программе, с которым она далее и работает. Для работы с файлами всех типов используется ряд процедур и функций:

assign(фп, файл)

Связывает файл с файловой переменной (ФП).

reset(фп)

Открывает существующий файл для чтения из него.

rewrite(фп)

Создает и открывает файл для записи в него.

close(фп)

Закрывает файл.

erase(фп)

Стирает файл (файл должен быть закрыт).

eof(фп)

Признак конца файла (True, если конец).

Ввод и вывод информации для типизированных и текстовых файлов производится процедурами:

read(f,x1,x2,…xn) или readln(f,x1,x2,…xn) – чтение информации х1,х2,…,xn из логического файла f.

write(f,x1,x2,…xn) или writeln(f,x1,x2,…xn) – запись информации х1,х2,… хn в логический файл f.

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

append(фп)

Открывает файл для дополнения.

eoln(фп)

Признак конца строки (True, если конец).

read(фп,переменные)

Считывает данные из файла.

readln(фп,переменные)

Считывает данные из файла, переходит на следующую строку.

write(фп,переменные)

Записывает данные в файл.

writeln(фп,переменные)

Записывает данные в файл, переходит на следующую строку.

Для нетекстовых файлов:

filesize(фп)

Число записей в файле.

filepos(фп)

Номер текущей записи.

seek(фп,номер)

Устанавливает указатель на запись с заданным номером.

truncate(фп)

Усекает файл до текущей позиции.

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

Задача 9-1. а). Вычислить по точкам функцию y=x/2 для x=0,0.5,1.0,…..4 и записать результаты в текстовый файл с именем func. Текстовый файл удобен тем, что его можно просмотреть в любом текстовом редакторе и, при желании откорректировать данные. Файлу не обязательно иметь расширение. Мы придали ему расширение txt с тем, чтобы проще было его просматривать в Проводнике или WinCommander (эти программы для файлов с расширением txt автоматически вызывают Блокнот). Физическому файлу дадим имя func.txt, а логическому имя f, и именно с ним будем работать.

б). Cоставить программу чтения из файла func.txt записанной ранее в него информации.

program 9_1a;{запись вычисленной функции в файл}
var f:
text;   {объявлен текстовый логический файл f}

x,y:real;

begin

{логический файл f связывается с физическим func.txt}

assign(f,'func.txt');

rewrite(f);  {файл f открывается для записи в него}

x:=0;

while x<=4 do begin  {вычисление в цикле функции}

 y:=x/2;  x:=x+0.5;

 writeln(f,x:3:1,y:4:1); {запись в файл переменных х и у}

end;

close(f);   {закрытие файла}

end.

program 9_1b;{чтение записанных ранее данных из файла}
var f:text;          
{объявлен текстовый файл f}
x,y:real; i:integer;
begin
assign(f,'func.txt');

reset(f);   {открытие файла для чтения}

for i:=1 to 9 do begin

 read(f,y,x);    {чтение из файла в память}

{вывод на монитор, считанной из файла информации}

 writeln('y=',y:3:1,' x=',x:4:1);  

end;

close (f);    {закрытие файла}

end.

файл

Vir

файл

Ved

tab

im

tarif

dn

im

zar

nalog

vid

таб

имя

тариф

дни

имя

зарплата

налог

выдать

35

Иван

100

20

Иван

2000

48

Петр

150

30

Петр

4500

15

Олег

200

10

Олег

3000

Задача 9-2. Посчитать зарплату рабочих. Сведения об их месячной выработке находятся в типизированном (типа record) файле VIR: табельный номер tab, имя im (длиной до 4-х знаков), дневной тариф tarif работника, число отработанных им за месяц дней dn. Эти данные вводятся оператором. На основании их компьютером подсчитывается и заполняется файл ведомости VED, содержащий имя im, зарплату zar (=tarif*dn), налог nalog (=13%*zar) и сумму к выдаче vid (=zar-nalog). Далее содержимое файла выводится с подсчетом итоговых сумм. Здесь придется написать две программы. Программой Vvod выполняется следующая последовательность действий: 1). Заполняется файл Vir. 2). Считывается содержимое Vir в массив V. 3). Выполняются все расчеты и заносятся в массив R. 4). Данные из R сохраняются в файле Ved. Программа Vivod реализует только два действия: вывод всей ведомости к оплате или вывод сведений только об одном работнике по запросу (по имени).

program Vvod; {ввод данных и сохранение результата}

uses crt;             {к задаче 9-2}

const n=3;

type vr=record  {объявление записи для Выработки}

  tab: integer;    {табель}   

  im: string[4];  {имя}

  tarif, dn: real;      

end;

vd=record   {объявление записи для Ведомости}

  im: string[4];

  zar, nalog, vid: real;

end;

var vir: file of vr;    {объявление файла Выработки}

      ved: file of vd;  {объявление файла Ведомости}

v: array[1..n] of vr; {массив V для ввода}

r: array[1..n] of vd; {массив R для расчета}

i: integer;

begin

clrscr;

{связывание логического и физического файлов}

assign(vir,'vir');  assign(ved,'ved');

rewrite(vir);           {открытие файла Vir для записи}

writeln('введите!');

writeln('табель, имя, тариф, дни');

for i:=1 to n do begin

 readln(v[i].tab); readln(v[i].im);

 readln(v[i].tarif); readln(v[i].dn);

 writeln(v[i].tab:2, v[i].im:6, v[i].tarif:3:0, v[i].dn:4:0);

 write(vir,v[i]); {занесение в файл Vir очередной записи}

end;

reset(vir);              {открытие файла Vir для чтения}

rewrite(ved);              {открытие файла Ved для записи}

for i:=1 to n do begin {вычисления}

 read(vir,v[i]);            {чтение записи из файла Vir}

 r[i].im:=v[i].im;          r[i].zar:=v[i].tarif*v[i].dn;

 r[i].nalog:=0.13*r[i].zar; r[i].vid:=r[i].zar-r[i].nalog;

 write(ved,r[i]); {занесение записи в файл Ved}

end;

reset(ved);     {открытие файла Ved для чтения}

for i:=1 to n do begin {печать}

 read(ved,r[i]);      {чтение записи из файла Ved}

 writeln(r[i].im:4, r[i].zar:5:0, r[i].nalog:7:2, r[i].vid:8:2);

end;

close(ved);close(vir); {закрытие файлов}

end.

program Vivod; {вывод данных по запросу}

uses crt;     {к задаче 9-2}

const n=3;

label m;

type

vd=record   {объявление записи для Ведомости}

  im: string[4];

  zar, nalog, vid: real;

end;

var ved: file of vd;   {объявление файла Ведомости}

r: array[1..n] of vd; {массив R для вывода}

xz,xn,xv:real;           {итоги: зарплата, налог, выдать}

i: integer;

x:string[4]; {искомое имя}

begin

clrscr;

assign(ved,'ved.txt');  

write('показать всех (0) или одного (имя)? '); readln(x);

writeln(' имя зарплата  налог  выдать');

reset(ved);     {открытие файла Ved для чтения}

if x='0' then begin {вывод всех работников}

 for i:=1 to n do begin

   read(ved,r[i]);     {чтение записи из Ved}

   writeln(r[i].im:4, r[i].zar:9:0, r[i].nalog:7:2, r[i].vid:8:2);

   {подсчет итогов}

   xz:=xz+r[i].zar; xn:=xn+r[i].nalog; xv:=xv+r[i].vid;

 end;

 writeln('Итог',xz:9:0,xn:7:2,xv:8:2) {вывод итогов}

end;

if x<>'0' then begin     {поиск и вывод одного имени}

 for i:=1 to n do begin

   read(ved,r[i]);

   if x=r[i].im then begin {если найдено - вывод и конец}

     writeln(r[i].im:4, r[i].zar:9:0, r[i].nalog:7:2, r[i].vid:8:2);

     goto m       {выход из цикла поиска}

   end;

 end;

 writeln('Не найдено имя: ',x);

m:end;

close(ved)

end.

Задача 9-3. Положим, в течение месяца работники бригады выполняли различные виды работ (пусть три), сведения о которых хранятся в трех файлах с именами Rab1, Rab2, Rab3. Кроме того, имеется справочный файл тарифов работников Tarif. Необходимо создать файл Ved ведомости на оплату, где будут собраны сведения о всех работниках и сделаны необходимые вычисления. Последовательность действий:

1. Предварительно создать на диске и заполнить файлы с именами Rab1, Rab2, Rab3 и Tarif. 

2. Последовательно считать все три файла в массив Mr[1..15].

3. Отсортировать массив по табельному номеру (по полю mr.tb). Повторяющиеся номера объединить (часы суммируются) в одну строку.

4. Считать файл Tarif в массив Mt[1..6]. Исходя из индивидуальных тарифов, рассчитать зарплату, налог и сумму к выдаче каждого и записать это в файл Ved.

5. Вывести из Ved полученные данные на экран вместе с общей суммой зарплат бригады.

Исходные данные и результаты показаны ниже. Над колонками приведены названия полей, принимающих соответствующие данные.

файл

Tarif

файл

Rab1

файл

Rab2

файл

Rab3

файл

Ved

tb

im

tr

tb

ch

tb

ch

tb

ch

tb

im

ch

zr

nl

vd

таб 

имя

тариф

таб

часы

таб

часы

таб

часы

таб

имя

часы

заработок

налог

выдать

35

Иван

50

8

30

15

40

35

50

8

Лена

120

3000

390,0

2610,0

48

Петр

30

20

50

48

20

8

40

15

Олег

50

1000

130,0

870,0

8

Лена

25

15

10

35

10

20

Вася

50

1750

227,5

1522,5

20

Вася

35

8

50

35

Иван

60

3000

390,0

2610,0

15

Олег

20

48

Петр

20

600

78,0

522,0

всего

300

9350

1215,5

8134,5

массив

MT

массив

MR

tb

im

tr

tb

ch

Программа Vedom реализует процесс обработки данных. Программу занесения данных в фалы Rab1, Rab2, Rab3, Tarif напишите сами.

program VEDOM;   {программа к задаче 9-3}

uses crt;

type     {создание типов записей}

rab=record tb,ch:integer end;   {тип записи Работы}

tar=record tb,tr:integer; im:string[4] end;            {тип записи Тарифы}

ved=record tb,ch,zr:integer; im:string; nl,vd:real end;  {тип записи Ведомость}

var    {создание файлов, рабочих записей и переменных}

r1,r2,r3:file of rab;   {файлы Работ}

mr:array [1..15] of rab;  {массив записей для приема данных из файлов Работ}

x: rab;      {запись типа Rab, необходимая для сортировки}

t:file of tar;           {файл тарифов}

mt:array [1..6] of tar;   {массив записей для приема данных из файла Тарифов}

v:file of ved;        {файл Ведомости}   

mv:ved;    {запись Ведомости}

sch,szr:integer; snl,zvd:real;  {переменные для накопления итоговых сумм в Ведомости}

m,i,j,k:integer; 

begin

clrscr;

{----------------------------------слияние Rab1-3  в массив записей MR------------------------------------}

assign(r1,'rab1'); assign(r2,'rab2'); assign(r3,'rab3'); reset(r1); reset(r2); reset(r3);

k:=0;

while not eof(r1) do begin k:=k+1; read(r1,mr[k]) end;

while not eof(r2) do begin k:=k+1; read(r2,mr[k]) end;

while not eof(r3) do begin k:=k+1; read(r3,mr[k]) end;

close(r1); close(r2); close(r3);

for i:=1 to k do writeln(mr[i].tb:3,mr[i].ch:4);  writeln; {вывод массива MR}

{-----------------------------------сортировка MR по табельному номеру----------------------------------}

for i:=1 to k-1 do begin;

 for j:=i+1 to k do if mr[i].tb>mr[j].tb then

   begin x:=mr[i]; mr[i]:=mr[j];mr[j]:=x end;

end;

for i:=1 to k do writeln(mr[i].tb:3,mr[i].ch:4);  writeln; {вывод отсортированного массива Работ}

{---обобщение записей с одинаковыми табельными номерами: для группы повторяющихся номеров

в первой записи производится суммирование часов, в остальных – поле номера устанавливается в 0}

i:=1;

while i<k do begin

 j:=1;

 while mr[i].tb=mr[i+j].tb do begin

 mr[i+j].tb:=0;  mr[i].ch:=mr[i].ch+mr[i+j].ch;  j:=j+1 end;

 i:=i+1

end;

for i:=1 to k do if mr[i].tb>0 then writeln(mr[i].tb:3,mr[i].ch:4); writeln; {вывод объединенного массива Работ}

{---------------------------------------считывание тарифов в массив Tar--------------------------------------}

assign(t,'tarif'); reset(t);

m:=0;             {количество строк тарифов}

while not eof(t) do begin m:=m+1; read(t,mt[m]) end;

for i:=1 to k do writeln(mt[i].tb:3,mt[i].im:6,mt[i].tr:5); writeln;

close(t);

{----------------------------------------расчет ведомости на оплату---------------------------------------------}

assign(v,'ved'); rewrite(v);

sch:=0;szr:=0;snl:=0;zvd:=0; {суммы}

for i:=1 to k do begin

if mr[i].tb=0 then continue;      {если номер пуст - пропуск}

mv.tb:=mr[i].tb; mv.ch:=mr[i].ch;

for j:=1 to m do begin            {поиск табеля в массиве MT}

    if mv.tb=mt[j].tb then begin {расчет}

       mv.im:=mt[j].im;         mv.zr:=mv.ch*mt[j].tr;

       mv.nl:=mv.zr*0.13;         mv.vd:=mv.zr-mv.nl;

       sch:=sch+mv.ch;   szr:=szr+mv.zr;

       snl:=snl+mv.nl;   zvd:=zvd+mv.vd;

       writeln(mv.tb:2,mv.im:5,mv.ch:4,mv.zr:5,mv.nl:5:0,mv.vd:5:0);

       write(v,mv);          {занесение записи в ведомость Ved}

       continue

    end;

end; {for j}

end; {for i}

mv.tb:=0; mv.im:='Итог'; mv.ch:=sch; mv.zr:=szr; mv.nl:=snl; mv.vd:=zvd;

write(v,mv); {занесение итоговой записи в ведомость Ved}

{----------------------------------------------печать ведомости-----------------------------------------------------}

reset(v);

writeln('      Платежная ведомость');

writeln('Таб Имя  Дни  Зарп  Налог Выдать');

while not eof(v) do begin

 read(v,mv);

 writeln(mv.tb:3,mv.im:5,mv.ch:4,mv.zr:6,mv.nl:7:1,mv.vd:7:1);

end;

end.

Задание. Составить программу вычисления суммы S(3х2) двух произвольных матриц А(3х2) и В(3х2) и записи матрицы S в файл sum типа Integer. Составить программу чтения и вывода из файла этой информации.

10. ПОДПРОГРАММЫ

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

 PROCEDURE имя_процедуры (список_параметров)

 FUNCTION имя_функции (список_параметров): тип_результата

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

Для обращения к процедуре нужно использовать оператор вида sum(a,b,c). Здесь переменные a,b,c называются фактическими параметрами, x,y,z – формальными. При исполнении процедуры значения a,b присваиваются x,y и выполняются вычисления. Их результат через переменную с передается в вызывающую процедуру. К функции можно обращаться, используя оператор вида c:=sum(a,b).

11. ГРАФИКА

Графический режим ПК зависят от типа монитора и видиоадаптера. Мы будем использовать лучший доступный режим: VGA, максимальное разрешение 640х480 точек (пискселей), 16 цветов. Соответствующий драйвер находится в файле EgaVga.bgi. Графический режим определяет команда

InitGraph(драйвер,мода,путь к файлу драйвера)

здесь: драйвер – номер драйвера (для VGA это 9), мода – номер режима (для 640х480 это 2), путь к файлу драйвера на диске. Если файл находится в директории Паскаля, путь можно не указывать, а ввести пустые кавычки. Параметры драйвер и мода можно не задавать. Тогда они будут определены автоматически.

Возврат в текстовый режим экрана:

CloseGraph.

Отсчет экранных координат начинается с левого верхнего угла: Х – вправо, Y – вниз.

Паскаль располагает функциями, позволяющими осуществлять элементарные графические построения:

GetMaxY

Вертикальный размер экрана по оси Y (в режиме VGA =479, поскольку отсчет точек от 0).

GetMaxX

Горизонтальный размер экрана по оси Х (в режиме VGA =639, поскольку отсчет от 0).

MoveTo(x,y)

Переместит курсор в позицию x,y.

MoveRel(dx,dy)

Переместит курсор от текущей точки на расстояние dx,dy.

ClearDevice

Очищает экран.

PutPixel(x,y,цвет)

Выводит заданным цветом точку в координатах x,y.

Line(x1,y1,x2,y2)

Проводит прямую от точки с координатами x1,y1 до x2,y2.

LineTo(x,y)

Проводит прямую от текущей точки до точки с координатами x,y.

LineRel(dx,dy)

Проводит прямую от текущей точки на расстояние dx,dy.

Rectangle(x1,y1,x2,y2)

Строит контур прямоугольника с координатами левого верхнего (x1,y1) и правого

нижнего (x2,y2) углов.

Bar(x1,y1,x2,y2)

Закрашивает прямоугольную область с координатами левого верхнего (x1,y1) и правого

нижнего (x2,y2) углов, установленным командой SetFillStyle, цветом.

Cyrcle(x,y,r)

Строит круг с центром в точке x,y и радиусом r.

Ellipse(x,y,угол1,

угол2,Rx,Ry)

Строит эллиптическую дугу с центром в точке x,y от начального угла1 (в градусах)

до угла2. Rx и Ry задают горизонтальный и вертикальный радиусы эллипса.

PieSlice(x,y,угол1,

угол2,r)

Строит сектор круга с центров в точке х,у радиусом r от угла1 (в целых градусах) до угла2. Заполнение и закрашивание секторов осуществляется функцией SetFillStyle.

SetFillStyle(

заполнение,цвет)

Определяет тип заполнения (0 нет, 1 сплошное, 2 горизонтальное, 3 штриховка /, 4 толстая штриховка / ,5 толстая штриховка \, 6 штриховка \, 7 +, 8 x, 9 клетка, 10 точки, 11 частые точки) и цвет заполнения фигур.

SetColor(цвет)

Устанавливает текущий цвет линий и символов: Black – 0, Blue – 1, Green – 2, Cyan – 3, Red –  4, Magenta – 5, Brown – 6, LightGray 7, DarkGray – 8, LightBlue – 9, LightGreen – 10, LightCyan – 11, LightRed – 12, LightMagenta – 13, Yellow – 14, White – 15.

SetBkColor(цвет)

Устанавливает текущий цвет фона.

SetLineStile(тип,

вид, толщина)

Устанавливает стиль линий. Тип: 0 – сплошная линия, 1– точечная,

2 – штрих-пунктир, 3 – пунктир. Вид: 0. Толщина: 1 или 3 пикселя.

Задача 11-1. Нарисовать на экране: 1). Две диагонали, пересекающиеся в центре. 2) Четыре концентрических окружности с центрами в центре экрана и радиусами 50, 100, 150, 200.

Задача 11-2. Вывести на кран функцию f(x)=sin(x)*x вместе с координатными осями. Аргумент Х изменяется от начального значения  Xn=0 до конечного Xk=20 с шагом dx=0.01. Главная проблема заключается в масштабировании исходной “натуральной” функции F в ее экранный вид Fэ: F(X)Fэ(Xэ). Здесь следует учесть, что экранные координаты расположены (рис. 11-2) не так как мы привыкли. Точка 0э,0э находится в его верхнем левом углу (а не в центре), ось Yэ идет вниз (а не вверх), ось Xэ – идет вправо. Т.о. для адекватного отображения графика на экране нам понадобится реализовать три действия:

1. Масштабировать диапазоны D изменения натуральных Х и Y к желаемым экранным, т.е. привести DХ и DY к DХэ и DYэ соответственно с помощью масштабных коэффициентов Mx=DХэ/Dx и My=DYэ/DY.

2. Перенести координаты так, чтобы максимум Yэ приходился на верхнюю границу экранной области, а начальное значение X – на левую ее границу.

3. Перевернуть направление графика. Поскольку направление экранной оси ординат противоположно натуральному, знак изменения Yэ должен быть противоположен знаку Y.

Программа имеет следующую структуру. 1). Описывается функция вычисления f(x). 2). Выясняются размеры экрана, параметры аргумента, проводится вертикальная координата. 3).Находятся максимальные значения Y. 4). Выполняется масштабирование переменных (msy и msx). Эти значения указывают, сколько пикселей приходится на единицу изменения Y и Х соответственно. 5). Выполняется собственно рисование кривой. Здесь оно выполнено двумя способами – точками и отрезками линий. Проверьте результат в обоих случаях, поочередно убрав одну из них. 6). Проводится ось Х.

program P11_2;

uses graph;

var d,m,rx,ry:integer;

x,y,xn,xk,ymin,ymax,dx:real;  msy,msx:real;

function f(x:real):real;   {вычисление функции}

begin f:=sin(x)*x  end;

begin

initgraph(d,m,'');      {переход в графический режим}

ry:=getmaxy+1; rx:=getmaxx+1; {размер экрана}

line(0,0,0,ry);         {ось Y}

xn:=0; xk:=60; dx:=0.01;{параметры аргумента}

x:=xn;      {начальное Х}

ymin:=f(x); ymax:=f(x);

while x<=xk do begin {поиск максимума и минимума Y}

  y:=f(x);

  if y>ymax then ymax:=y;

  if y<ymin then ymin:=y;

  x:=x+dx;                {изменяем Х}

end;

msy:=ry/abs(ymax-ymin); {масштаб по Y}

msx:=rx/abs(xk-xn);          {масштаб по X}

x:=xn;      {начальное Х}

while x<=xk do begin    {рисование}

y:=f(x);

putpixel(round((x-xn)*msx),-round((y-ymax)*msy),2); {точки}

lineto(round((x-xn)*msx),-round((y-ymax)*msy));  {отрезки}

 x:=x+dx;               {изменяем Х}

end;

line(0,-round(-ymax*msy),rx,-round(-ymax*msy)); {ось Х}

readln; {пауза для просмотра картинки}

closegraph;

end.

Задания.

а). Решить аналогичную задачу, но ось Y направить горизонтально, а Х – вертикально.

б). Известна зарплата (массив zar[1..5]) работников (N=5) бригады. Построить диаграмму из вертикальных линий.

в). Условие то же, но диаграмма столбиковая. Замечание. Ширина столбца определяется делением ширины экрана на число рабочих. Однако, если ширина столбца не кратна размеру экрана, крайний столбец будет отображен не полностью. При программировании следует учесть этот фактор, уменьшив ширину столбца.

г). Известна зарплата (массив zar[1..5]) и премия (массив p[1..5]) каждого из N=5 работников бригады. Построить совмещенную столбиковую диаграмму (на столбике зарплаты стоит столбик премии). Премия должна быть заштрихована командой SetFillStyle.

д). Для той же задачи построить секторную диаграмму зарплат. Подсказка. Сначала следует найти сумму всех зарплат s. Затем перевести зарплату каждого работника в градусы его сектора на диаграмме zar[i]/s*360 и запомнить ее в массиве zar[1..5]. Далее вычислить начальный и конечный угол каждого радиуса каждого сектора, нарисовать диаграмму командой PieSlice и раскрасить ее.


program P
5_5;

про

верка

для n=3

var i,n,s:integer;

begin

1

цикл

2

цикл

3

цикл

4

цикл

s:=0; a:=3;

readln(n);

for i:=1 to n do begin

  s:=s+a;

  a:=2*a;

end;

writeln(s);

end.

a=3, s=0

n=3

i=1<3

s=0+3=3

a=2*3=6

2<3

3+6=9

12

3=3

9+12=21

24

4>3

s=21

Рис.5-1а

N

1

нет

program P7_1;

const x='Петров Саша';

var n:integer;y:string;

begin;

n:=pos(' ',x); {n=7}

y:=copy(x,n+1,length(x))'; {y=Саша}

y:=y+’ ‘+copy(x,1,n-1);

writeln(y); {y=Саша Петров}

end.

program P6_3;

var i,j,n,m: integer;       

x:array [1..10] of integer;

begin

write('n='); readln(n);

for i:=1 to n do x[i]:=i;

for i:=1 to n-1 do    

for j:=i+1 to n do if x[i]<x[j] then

   begin m:=x[i]; x[i]:=x[j]; x[j]:=m end;

for i:=1 to n do write(x[i],’ ‘);

end.

program P7_2; {второй вариант}

. . .

j:=1;

{пропускаем начальные пробелы}

while x[j]=' ' do j:=j+1;

for i:=j to length(x)-1 do

   if (x[i]=' ') and (x[i+1]<>' ') then k:=k+1;

writeln('найдено слов=',k+1);

program P7_2; {первый вариант}

var k,i:integer; x: string;

begin

writeln(‘введите предложение’); readln (x);

k:=0;

for i:=1 to length(x) do if x[i]=’ ‘ then k:=k+1;

writeln('найдено слов=',k+1);

end.

моет посуду

8

7

нет

program krug;  {имя программы}

uses crt; {подключение библиотеки CRT}

var s,r: real; {переменные – вещественные}

begin {начало вычислительной части}

clrscr;  {очистка экрана}

write('радиус='); {вывод слова-подсказки}

readln(r);  {ввод радиуса}

s:=pi*r*r;  ычисление площади}

write('площадь=',s:6:2); {вывод площади}

readkey;  {оператор задержки}

end.  {конец программы}

2.5

6·K

XC+

да

X=0

X=0

ввод Х

Y=X/2

печать Y

ввод  Х

нет

начало

6

5

4

2

3

1

program P6-2;

var n,i,j:integer; s,y,sr:real; x: array [1..10,1..5] of real;

begin

readln(n); {число вкладов (до 10)}

for i:=1 to n do; for j:=1 to 4 do begin {ввод сведений о вкладах}

   write('введите остаток по вкладу номер', i,'за', j ,'квартал');

   readln(x[i,j]);

end;

s:=0;

writeln(' Счет №      Остатки по кварталам');

writeln('                I           II         III       IV      ВСЕГО');

for i:=1 to n do begin                {вычисление годового остатка}

     y:=(x[i,1]+x[i,2]+x[i,3]+x[i,4])/4;     {средний остаток}

     if y<=5000 then y:=1.1*y;

     if (y>5000) and (y<=10000) then y:=1.15*y;

     if y>10000 then y:=1.2*y;

     x[i,5]:=x[i,4]+y;      {остаток вклада с начислениями}

     writeln(i,x[i,1],x[i,2],x[i,3],x[i,4],x[i,5]);

     s:=s+x[i,5];

end;

sr:=s/n;

writeln('Сумма всех вкладов в банке = ',s);

writeln('Средний вклад = ',sr);

end.

N

Рис. 3-1а

Анализ счетчика на выход

его из заданного значения

нет

да

тело цикла

Обрабатывающая часть цикла

Приращение счетчика цикла

+

B·3

   F   

8.4

T5

да

да

да

        Y

 Y=5+X           Y=5                     Y=10–0,5X

                 0                  10                            X

y=10-0,5х

 C·B  

нет

program P4_1; {возраст}

var t:integer; p:char;

begin 

t:=80; p:='ж';

case t  of

0..17:   write('детство');

20..30:write('молодость');

31..54: write('зрелость');

else if (p='ж') or (t>=60)

     then write('пенсия')   

     else write('зрелость')

end   end.

y=5

program P5_2; {другой вариант}

var x,y: real;

begin

x:=3;

while x<=9 do begin

  y:=sqr(x–6);  writeln(x,y); x:=x+2;

end;

end.

A = [A1, A2, A3, ... AК]

 B11, B12, ... B1M

B =  B21, B21, ... B2M

. . . . .

 BN1, BN2, ... BNM

y=5+x

х≥10

х<10

        5+X   при Х<0

Y =  5   при 0≤Х<10

10–0,5X   при X≥10

y=y+r     y=1,

r=r*x/i    r=1,

i=i+1       i=1.

program P5_7;

uses crt;

const e=0.001;   {погрешность}

var i,j:integer; x,y,r:real;

begin

clrscr;

write(‘введите Х ’); readline(x);

r:=1; y:=r; i:=1;

while r>e do begin;

 r:=r*x/i;   y:=y+r;   i:=i+1;

 writeln(i,'-ый член=',r:6:4,'  Y=',y:6:4);

end;

write('exp(x)=',exp(x):8:4) {проверка}

end.

Задание начальных значений

циклических переменных и счетчика

нет

х<0

ввод х

rogram Имя программы

uses Подсоединение библиотек

label Перечисление меток

var Описание переменных;

type Описание типов

const Описание констант;

begin

      Собственно программа

end.

Рис.5-6

Рис. 5-1б

Рис. 3-1в

x=0

нет

s=s+x

да

да

нет

нет

печать s,p,kp

печать “нулей нет”

kp=kp+1, p=p*x

x<0

ввод x

i=1,n

Рис. Организация цикла

ввод n

p=1, s=0, kp=1

program P5_8;

var y,x,z: integer;

begin

for x:=0 to 4 do

for z:=0 to 10 do begin

   y:=x*x+z;   

   writeln(‘x=’,x,  z=’,z,  y=’,y)  

   end;

end.

да

program P5_4;

проверка для n=3 и x=2,4,3

var n,s,x:integer;

begin

1

цикл

2

цикл

3

цикл

writeln(n);

s:=0;

for i:=1 to n do begin

   readln(x);

   s:=s+x;

end;

writeln(s);

end.

n=3

s=0

1<3

x=2

s=2

2<3

4

6

3=3

3

9

4>3

s=9

Замечание. С целью придания наглядности подчиненные (вложенные) операторы удобно вводить с некоторым отступом, как показано слева.

да

procedure Sum(x,y,s:real);  function Sum(x,y:real):real;

begin         begin

s:=x+y         sum:=x+y

end;         end;

program P3_2;

label k;   var a,b,c: real;

begin

readln(a,b,c);

if a+b>=c then goto k;

writeln('Неверно'); exit;

k: if  b*b>a then begin

 writeln('Верно'); exit end;

writeln('Неверно')

end.

x:=0;  {есть числа <0?}

if a<0 then x:=x+1;

if b<0 then x:=x+1;

if c<0  then x:=x+1;

if x=1 then write('верно')

       else write('неверно');

вывод у

нет

Рис.5-5

  

  for ... do begin

      ...

      break;

      ...

      continue;

   end;

   ...

да

нет

печать S

S=S+A, A=2A

I=1,N

ввод N

A=3, S=0

Действие операторов

break и continue

1

Y=(X-6)2

Y

Рис.5-2а

Y

X

3          5         7        9

Рис. 5-2б

     A1   A2    A3    A4

S = 3  +  6  + 12  + 24  + ... = åАi

  

       

     S1     S2    S3      S4      

P=P+ZA,       P=1

A=A-2,         A=3

Z=–Z         Z=–1

Рис. 5-3

да

конец

I>4

Y=(X-6)2

вывод X,Y

X=X+2

I=I+1

нет

Х=3  I=1

program P5_1;

label m;

var x,y: real;

begin

m:readln(x);

   IF x=0 then exit;

   y:=x/2;

   writeln(x,y);

goto m;

end.

program P5_2;

Проверка

label k;

var x,y:real;

begin

1

цикл

2

цикл

3

цикл

4

цикл

x:=3;

k: if x>9 then exit;

   y:=sqr(x–6);

   writeln(x,y);

   x:=x+2;

goto k;

end.

x=3

x=3<9

y=9

3, 9

x=3+2=5

5<9

y=1

5, 1

x=7

7<9

y=1

7, 1

x=9

9=9

y=9

9, 9

x=11

11>9

конец

да

конец

X>9

Y=(X-6)2

печать X,Y

X=X+2

да

нет

нет

да

да

y=10-0,5х

y=5

y=5+x

х≥10

0≤х и х<10

х<0

ввод х

Рис. 3-1б

вывод у

нет

program P3_1; {второй вариант}

label m;

var x,y: real;

begin

readln(x);

if x<0  then begin y:=5+x; goto m end;

if x<10 then begin y:=5; goto m end;

if x>=10 then y:=10-0.5*x;

m: writeln(y:6:2)

end.

program P3_1;

var x,y: real;

begin

readln(x);

if x<0 then y:=5+x;

if (0<=x)and(x<10) then y:=5;

if x>=10 then y:=10–0.5*x;

writeln(‘y=’,y:6:2)

end.

нет

Х=3

Пример (справа). Здесь сначала описан тип записи Vr, состоящей из полей: tab, im, tarif, dn соответствующих типов. Затем в разделе Var описаны уже конкретные (рабочие) записи: X и массив записей Y. Обращаться к элементам записей нужно, используя полное имя (имя записи.имя поля), например x.tarif, x.im. А для массива записей нужно указывать и индекс: y[3].tarif. Записи удобно использовать при работе с файлами.

IF a>0 THEN WRITELN(a)

ELSE IF b>0 THEN WRITELN(b)

ELSE IF c>0 THEN WRITELN(c)

ELSE WRITELN(все числа <0’);

TYPE имя типа=RECORD

     описание элементов записи

    END;

Задача 3-2. Даны три произвольных числа А, В, С. Составить программу, которая анализирует их и, если сумма первых двух чисел не меньше третьего, а квадрат второго больше первого – выдает сообщение ВЕРНО. Если хотя бы одно из условий не выполняется, – то сообщение НЕВЕРНО (program P3_2 рис. 3-2).

Несмотря на простое условие, программа получилась достаточно запутанной. При необходимости выполнять анализ одновременно нескольких условий удобно пользоваться логическими функциями. Аргументами логических функций являются высказывания, в отношении которые могут быть либо истинными, либо ложными. К таким высказываниям относятся операции отношения (равно, больше, меньше и т.д.). Так, например, отношение вида Х=Y всегда может быть только истинным или только ложным.

CASE выражение OF

   константа1: оператор1;

   константа2: оператор2;

. . .

   ELSE операторN;

   END;

program P4_1; {символы}

var s:char; 

begin

write('введите символ '); read(s);

case s of

'A'..'Z','a'..'z':  write('латиский');

'А'..'Я','а'..'п','р'..'я','Ё','ё': write('русский'); 

'0'..'9':         write('цифры');

'+','-','/','*':  write('знаки операций');

',','.',';':         write('знаки препинания');

else       write('вспомогательные знаки')

end

end.

а)                б)                в)                 г)                д)

program P11_1

uses graph;

var d,i,m,rx,ry:integer;

begin

initgraph(d,m,'');   {переход в графику}

ry:=getmaxy; rx:=getmaxx; {размер экрана}

line(0,0,rx,ry);    {первая диагональ}

line(0,ry,rx,0);    {вторая диагональ}

for i:=1 to 4 do begin{окружности}

 circle(rx div 2,ry div 2,50*i);

end;

readln;        {пауза для просмотра результата}

closegraph; {закрытие графического режима}

end.

Рис.11-2

Yэ

Хэ

Экран

Xэ=0

Yэ=0

program P7_3;

var x:string[1]; d:string; i:integer;

const s:string='абвxyz123ABC'; {тестовый пример}

begin

d:='';

for i:=1 to length(s) do begin {перебор символов в S}

  x:=copy(s,i,1);   {очередной символ заносится в Х}

  {если ‘а’<=буква<=’п’, код уменьшаем на 32}

  if (x>='а')and(x<='п') then x:=chr(ord(x[1])-32);

  {если ‘р’<=буква<=’я’, код уменьшаем на 80}

  if (x>='р')and(x<='я') then x:=chr(ord(x[1])-80);

  {латинские преобразуем в заглавные}

  if x<'А' then x:=upcase(x[1]);  

  d:=d+x; {заполнение слова D}

end;

write(d);   {результат:  'АБВXYZ123ABC'}

end.

конец

Замечание. Предложенное решение имеет недостаток. Хотя данные и хранятся в файлах, обрабатываются они в массивах. Т.е., если объем данных велик и они не могут быть размещены в основной памяти (в виду ограниченности ее объема), этот метод непригоден. На практике, возможно, придется обрабатывать данные непосредственно в файлах.

В приведенной программе для наглядности предусмотрен вывод всех промежуточных данных.

Рис. 3-2

нет

да

да

В2>C

А+В³C

конец

печать

Неверно

печать

Верно

ввод А,В,С

нет

ВЕРНО”     если А+В>=C и В2 >A

НЕВЕРНО” – в противном случае

конец

X=0

ввод Х

Y=X/2

печать Y

нет

начало

да


 

А также другие работы, которые могут Вас заинтересовать

38960. Методы моделирования на этапе проектирования ТВК. Достоинства и недостатки математического (компьютерного) и физического моделирования 30 KB
  Методы математического и физического моделирования проектируемой системы помогают решать задачи связанные с уточнением параметров решающих правил при реализации различных алгоритмов обработки сигналов в ТВК. Они способствуют выявлению обоснованных требований к отдельным звеньям системы особенно в тех случаях когда аналитические расчётные методики оказываются малоэффективными или достаточно сложными. Эта модель обычно включает в себя модели основных звеньев системы: изображения объекта оптической системы фотоприёмного узла анализатора...
38961. Задачи, решаемые на этапе предварительной обработки изображений в ТВК. Назовите и поясните некоторые из методов, которые могут использоваться для решения этих задач 53.5 KB
  Сокращение массива [E ij ] за счет исключения отсчетов сигнала от фона; – использование алгоритмов сглаживания для подавления некоррелированных шумов; – применение методов трансформирования двумерных массивов исходных изображений в двумерные массивы коэффициентов на основе ортогональных преобразований для последующей фильтрации выделения признаков наблюдаемых объектов и т. Подробнее рассмотрим алгоритмы предварительной фильтрации используемые при решении задачи обнаружения и селекции точечных объектов при наличии неоднородного фона....
38962. Алгоритмы трансформирования исходных изображений на основе ортогональных преобразований 68 KB
  Алгоритмы трансформирования исходных изображений на основе ортогональных преобразований С какой целью могут использоваться алгоритмы трансформирования исходных изображений на основе ортогональных преобразований Что общего и в чём различия между дискретным преобразованием Фурье и другими видами ортогональных преобразований. Один из видов ортогональных преобразований дискретное преобразование Фурье. В процессе ортогональных преобразований изображения имеющего сильные корреляционные связи между соседними элементами происходит...
38963. Алгоритмы выделения границ (контуров) объектов наблюдения в полутоновых и бинарных изображениях 166 KB
  После этого границы объекта могут быть найдены следующим образом.15 где: ij ∈ωгр – множество координат точек принадлежащих области изображения вблизи границ объекта; D – пороговое значение нормы градиента.15 обычно недостаточно для успешного выделения контуров объекта. Изменяя величину D можно в принципе менять соотношение между вероятностью выделения лишних точек ошибки первого рода и вероятностью пропуска контурных точек объекта ошибки второго рода.
38964. Методы автоматической идентификации объектов без выделения геометрических признаков. Их достоинства и недостатки 46.5 KB
  Идентификация заключается в сравнении изображения одного объекта со всеми эталонами заданного класса. Способ прямого сравнения изображения объекта с эталонным изображением. Пусть [Eij] – исходное изображение объекта; [Fij] – эталонное изображение.4 и следовательно могут возникнуть ошибки связанные с неправильной идентификацией объекта ошибки первого рода.
38965. Классификация телевизионных вычислительных комплексов (ТВК). На каких разделах теории статистических решений базируется разработка ТВК, решающих задачи обнаружения, распознавания или измерения параметров объектов наблюдения. Приведите примеры подобных зад 35.5 KB
  На каких разделах теории статистических решений базируется разработка ТВК решающих задачи обнаружения распознавания или измерения параметров объектов наблюдения. Приведите примеры подобных задач Понятие телевизионные вычислительные комплексы ТВК включает в себя очень широкий спектр телевизионных систем ТС предназначенных для решения самых разнообразных задач так или иначе связанных с наблюдением за объектами. Научной основой для проектирования ТВК является теория статистических решений включающая в себя три основных раздела: теорию...
38966. Виды и методы выделения геометрических признаков объектов, используемых в ТВК при автоматической идентификации объектов. Методы достижения инвариантности признаков к масштабу изображения объектов 172.5 KB
  Методы достижения инвариантности признаков к масштабу изображения объектов Литвинов Виды: Определение площади и периметра Площадь есть число элементов S относящихся к объекту массиву чисел L. агр – множество граничных точек изображения объекта вычисляются предварительно Для достижения инвариантности к масштабу используют нормируемые признаки: U = P2 V = P 1 2 Определение радиусов вписанных и описанных окружностей Состоит из 2х этапов: А Определение координат геометрического центра изображения объекта: Б Вычисление...
38967. Особенности представления сигналов в ТВК. Основные способы сопряжения телевизионных датчиков с цифровым вычислительным устройством (ЦВУ), предопределяющие архитектуру ТВК. Их достоинства и недостатки 55 KB
  Основные способы сопряжения телевизионных датчиков с цифровым вычислительным устройством ЦВУ предопределяющие архитектуру ТВК. Посредством устройства вводавывода УВВ данные накапливаемые в БЗУ могут пересылаться в оперативную память цифрового вычислительного устройства ЦВУ и подвергаться дальнейшей обработке в соответствии с запрограммированным алгоритмом. Таким образом БЗУ служит для обеспечения условий независимой работы ТД и ЦВУ функционирующих до начала передачи данных в асинхронном режиме. Тогда ЦВУ в соответствии с...