- •Программирование на языке паскаль Учебное пособие
- •1. Общая характеристика языков программирования
- •1.1. Языки программирования
- •1.2. Трансляторы
- •1.3. История создания языков
- •1.4. Базовые структуры языков программирования
- •Контрольные вопросы
- •2. Описание языка паскаль
- •2.1. Основные объекты языка
- •2.2. Структура Паскаль-программы
- •2.3. Типизация данных
- •2.4. Объявление данных
- •Контрольные вопросы
- •3. Простые операторы. Ввод/вывод данных
- •3.1. Оператор присваивания и выражения
- •3.2. Операторы вызова процедур. Ввод/вывод данных
- •3.2.1. Процедуры ввода read и readln
- •Общая форма записи оператора
- •3.2.2. Процедуры вывода write и writeln
- •Контрольные вопросы
- •Каково назначение процедуры writeln без параметров? Задания для самостоятельной работы
- •Варианты заданий
- •Дополнительные задания
- •4. Структурные операторы. Организация ветвлений и циклов
- •4.1. Составной и пустой операторы
- •4.2. Организация ветвлений. Операторы выбора
- •4.2.1. Оператор ветвления if
- •4.2.2. Оператор варианта case
- •Общая форма записи
- •Контрольные вопросы
- •Задания для самостоятельной работы
- •Варианты заданий
- •Дополнительные задания
- •4.3. Организация циклов. Операторы повторения
- •4.3.1. Оператор while
- •4.3.2. Оператор repeat
- •4.3.3. Оператор for
- •Контрольные вопросы
- •Задания для самостоятельной работы
- •Варианты заданий
- •5. Организация подпрограмм. Процедуры и функции
- •5.1. Процедуры и их типизация
- •5.1.1. Встроенные процедуры
- •5.1.2. Процедуры пользователя
- •5.1.3. Процедуры без параметров
- •5.1.4. Фактические и формальные параметры
- •5.1.5. Локальные и глобальные переменные
- •5.1.6. Процедуры с параметрами-значениями
- •5.1.7. Процедуры с параметрами-переменными
- •5.1.8. Комбинированные процедуры
- •5.2. Функции пользователя. Рекурсивные функции
- •5.2.1. Определение функции
- •О бщая форма записи заголовка функции
- •5.2.2. Функции пользователя
- •5.2.3. Рекурсивные функции
- •Контрольные вопросы
- •Задания для самостоятельной работы
- •Варианты заданий
- •Дополнительные задания
- •6. Массивы. Данные типа array
- •Одномерные массивы
- •Общая форма записи
- •Общая форма записи
- •6.2. Многомерные массивы
- •6.3. Способы работы с массивами
- •Контрольные вопросы
- •Задания для самостоятельной работы
- •Варианты заданий
- •Дополнительные задания
- •Обработка литерных величин. Данные типа char и string
- •7.1. Тип данных char
- •Работа программы
- •7.2. Массивы литер
- •7.3. Тип данных string
- •7.4. Строковые функции и процедуры
- •Контрольные вопросы
- •Задания для самостоятельной работы
- •Варианты заданий
- •Дополнительные задания
- •8. Множества. Данные типа set
- •О бщий вид регулярного типа
- •8.1. Определение типа set
- •8.2. Операции над множествами
- •8.2.1. Принадлежность множеству
- •8.2.2. Сравнение множеств
- •8.2.3. Действия над множествами
- •8.3. Вывод множеств
- •Контрольные вопросы
- •Задания для самостоятельной работы
- •Варианты заданий
- •9. Комбинированный тип. Данные типа record
- •9.1. Оператор типа record
- •9.2. Оператор with
- •9.3. Записи с вариантами
- •Контрольные вопросы
- •Задания для самостоятельной работы
- •Варианты заданий
- •10. Файловый тип
- •10.1. Определение и описание типизированного файла
- •Общая форма записи
- •10.2. Типы файлов. Процедура работы с файлами
- •10.3. Основные приемы работы с файлами
- •10.4. Текстовые файлы
- •Контрольные вопросы
- •Задания для самостоятельной работы
- •Типизированные файлы
- •Текстовые файлы
- •Программирование графики
- •Основные понятия компьютерной графики
- •Формирование изображения на экране
- •Инициализация графического режима
- •Простейшие графические операторы (процедуры)
- •Основные приемы работы с графикой
- •Работа с цветом
- •Заполнение (закрашивание) произвольной замкнутой фигуры
- •Построение простейших геометрических фигур
- •Контрольные вопросы
- •Задания для самостоятельной работы
- •Варианты заданий
- •Библиографический список
8.2.3. Действия над множествами
В Паскале, как и в математике, над множествами можно выполнять следующие логические операции:
– объединение;
– пересечение;
– разность.
Рассмотрим эти операции подробно, но предварительно произведем описание:
type COUNTRIES = (ENG, FR, USA, SP, IT);
var MAP1, MAP2: COUNTRIES.
а) ОБЪЕДИНЕНИЕ (+) : [ENG, FR] + [IT] = [ENG, FR, IT];
б) ПЕРЕСЕЧЕНИЕ (*) : [ENG, FR, USA] * [ENG, USA, IT] = [ENG, USA];
в) РАЗНОСТЬ (-) : [ENG..IT] – [ENG..SP] = [IT].
Эти три операции используются для построения выражений над множествами, например:
MAP1 := [FR];
MAP1 := MAP1 + [USA];
MAP2 := MAP1;
MAP1 := MAP1 * (MAP2 + [IT]).
П р и м е р. Решето Эратосфена. Найти все простые числа, не превосходящие заданного числа.
Алгоритм базируется на вычеркивании чисел, кратных выбранному.
program ERATOS;
const MAXPRIM = 15;
var PRIMES: set of 2..MAXPRIM;
COUNT, MULTIPLE: integer;
begin
¦ writeln ('простые числа, меньше ', MAXPRIM);
¦ PRIMES := [2..MAXPRIM];
¦ for COUNT := 2 to MAXPRIM do
¦ if COUNT in PRIMES then
¦ begin
¦ ¦ writeln (COUNT);
¦ ¦ for MULTIPLE := 1 to (MAXPRIM div COUNT) do
¦ ¦ PRIMES := PRIMES - [COUNT*MULTIPLE]
¦ end;
end.
Примечание. Программа работает с множеством, состоящим из всех целых чисел в интервале 2 ... 15. В ней при помощи цикла FOR проверяется каждое целое число, входящее в множество. Если оно является элементом множества, то печатается и из множества удаляются все целые числа, кратные данному числу.
8.3. Вывод множеств
При работе с множествами немаловажным является вопрос вывода на экран элементов множества. Отметим, что в большинстве версий языка в операторах WRITE нельзя называть переменные типа ARRAY. Например, нельзя вывести множество таким образом:
VAR A : SET OF 1..9;
...................
WRITE (A).
Здесь нет ничего удивительного, так как даже если А есть массив, то его тоже нельзя распечатать сразу с помощью одного оператора WRITE (А). Для вывода элементов массива организуются циклы.
Для вывода элементов множества также нужно организовать цикл (однократный), внутрь которого вводится некоторая переменная, пробегающая все возможные значения этого множества, а перед оператором WRITE в рамках конструкции IF проверяется, входит ли этот элемент в конкретное множество:
if K in SET1 then write (K).
Как правило, для целей распечатки элементов множеств организуются свои процедуры. Пусть мы имеем дело с множествами, состоящими из целых чисел в границах NIZ и VERH. Зададим множественный тип TS для этих границ:
type INT = NIZ..VERH; TS = set оf INT.
Тогда можно написать процедуру, содержащую в качестве параметра множество:
procedure PRINTSET (OS : TS);
var M: INT;
begin
¦ for M := NIZ to VERH do
¦ if M in OS then writeln (M);
end.
Теперь можно обращаться к этой процедуре для печати множеств, если только они состоят из элементов, не выходящих из интервала NIZ …VERH. Пусть в разделе констант было описано:
const NIZ = 0; VERH = 10.
Тогда можно вывести на экран элементы множества, обратившись к процедуре:
а) PRINTSET ([5, 6, 7]);
б) PRINTSET ([2]);
в) PRINTSET ([3..8]).
Обращение к процедуре можно организовать также в виде:
var SET1, SET2 : TS;
..................
SET1:= [...]; SET2 := [...]
PRINTSET (SET1); PRINTSET (SET1 + SET2); и т.д.
П р и м е р . В заключение рассмотрим пример целиком, где продемонстрируем все те действия, которые определены над множествами.
program IGRA;
type KOST = 1..6; BROSOK = set of KOST;
var A, B, C : BROSOK;
procedure SRAWNENIE (D : BROSOK);
var K : KOST;
begin
¦ for K := 1 to 6 do
¦ if K in D then write (K:4); writeln;
end;
begin
¦ A := [1, 3, 4]; B := [2, 4, 6];
C := A + B;
¦ write ('[1, 3, 4] + [2, 4, 6] ='); SRAWNENIE (C);
¦ C := A – B;
¦ write ('[1, 3, 4] – [2, 4, 6] ='); SRAWNENIE (C);
¦ C := A * B;
¦ write ('[1, 3, 4] * [2, 4, 6] ='); SRAWNENIE (C);
end.
Примечание. В программе определяются множества A, B, C типа BROSOK, элементами которых являются целые числа из диапазона [1..6], и процедура вывода на экран элементов таких множеств.
Затем задаются множества A и B, находятся различные значения множества C и выводятся его элементы.
Замечание 1. Если множество задано перечислимым типом, то его элементы напечатать нельзя. На печать можно вывести элементы только ординального типа: INTEGER, CHAR, BOOLEAN, интервальный.
Замечание 2. Один и тот же набор данных можно организовать в виде линейного массива ARRAY, в виде множества SET и в виде строки типа STRING. Какой из этих видов предпочтительнее? Если над элементами (числами) производятся действия, то лучше ARRAY. Если же стоит задача о взаимосвязи элементов нескольких множеств или вопрос о вхождении каких-то объектов в множество, то лучше SET.
Например, проверить, входит ли некоторая буква в заданный текст, можно двумя способами:
var TX : set of 'a'..'z';
BW : char;
----------------
TX := [‘a’..’m’];
Readln (BW);
1-й с п о с о б 2-й с п о с о б
OTWET := 'нет';
for k := 1 to 20 do if BW in TX then writeln ('да').
if BW = TX [k] then OTWET := ‘да’;
writeln (ОTWET);
Из приведенных фрагментов программ видно, что 2-й способ в данном случае предпочтительнее, так как здесь для определения вхождения буквы в текст достаточно однократного использования оператора IF, тогда как в первом случае для этого используется многократное применение того же оператора IF в операторе цикла FOR.