лекции презентации

Post on 17-Jun-2015

658 views 2 download

Transcript of лекции презентации

Лекция №1

Введение

Эволюция языков программирования

Программирование на языке высокого уровня

Введение

Дисциплина: Программирование на языке

высокого уровня. Основы программирования

Лектор: Шершуков Кирилл Вячеславович

Расписание занятий

Содержание дисциплины

1-й семестр: Основы алгоритмизации и

программирования на языке Pascal 1 лекция в неделю, 8 лабораторных

работ 3 аттестации – 2 текущие по 30

баллов (9, 17 неделя) и зачет 40 баллов

Литература

Павловская Т.А. Паскаль. Программирование на языке высокого уровня. Учебник для ВУЗов. СПб: «Питер», 2007. – 393с.

Фаронов В.В. Turbo Pascal 7.0 Начальный курс. Учебное пособие. М.: «ОМД Групп», 2003.- 616с.

Павловская Т.А. Паскаль. Программирование на языке высокого уровня. Практикум. СПб: «Питер», 2007. – 317с.

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

История языков развития программирования тесным образом связана с историей вычислительных машин. Даже простые арифметические операции с большими числами затруднительны для человеческого мозга. Поэтому уже в древности появилось простейшее счетное устройство - абак. В семнадцатом веке была изобретена логарифмическая линейка. В 1642 году Блез Паскаль сконструировал восьмиразрядный суммирующий механизм. В 1820 году француз Шарль де Кольмар создал арифмометр, способный производить умножение и деление.

Первая программируемая вычислительная машина

Все основные идеи, которые лежат в основе работы компьютеров, были изложены еще в 1833 году английским математиком Чарльзом Бэббиджем (1791-1871). Он разработал проект машины для выполнения научных и технических расчетов, где предугадал основные устройства современного компьютера, а также его задачи. Управление такой машиной должно было осуществляться программным путем. Для ввода и вывода данных Бэббидж предлагал использовать перфокарты. В то время перфокарты уже использовались в текстильной промышленности.

Первый язык программирования

Первый язык программирования разработала Лавлейс Огаста Ада Кинг (1815 – 1852) для машины Бэбиджа.В комментариях к описанию машины, изданном в 1843 году, введены понятия «операция», «переменная», «условный переход», «цикл». Приведена программа для решения системы двух линейных уравнений с двумя неизвестными

Создание компании IBM

В 1888 году американский инженер Герман Холлерит сконструировал первую электромеханическую счетную машину. Эта машина, названная табулятором, могла считывать и сортировать статистические записи, закодированные на перфокартах. В 1890 году изобретение Холлерита было впервые использовано в 11-й американской переписи населения. Работа, которую пятьсот сотрудников выполняли в течение семи лет, Холлерит сделал с 43 помощниками на 43 табуляторах за один месяц.    В 1896 году Герман Холлерит основал фирму Computing Tabulating Recording Company, которая стала основой для будущей International Business Machines Corporation (IBM).

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

В 1946 в США была создана первая электронная вычислительная машина (ЭВМ) - ENIAC (Electronic Numerical integrator and Computer - Электронный числовой интегратор и компьютер). Разработчики: Джон Мочи (John Маuchу) и Дж. Преспер Эккерт (J. Prosper Eckert).    Он был произведен на свет в Школе электрической техники Moore (при университете в Пенсильвании).    Время сложения - 200 мкс, умножения - 2800 мкс и деления - 24000 мкс.     Компьютер содержал 17468 вакуумных ламп шестнадцати типов, 7200 кристаллических диодов и 4100 магнитных элементов.  Общая стоимость базовой машины - 750000 долларов.

Первая советская ЭВМ

В Советском Союзе первая электронная цифровая вычислительная машина была разработана в 1950 году под руководством академика С. А. Лебедева в Академии наук Украинской ССР. Она называлась «МЭСМ» (малая электронная счётная машина).

Возникновение компьютерной науки (Computer Science)

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

Первое поколение ЭВМ

Развитие ЭВМ делится на несколько периодов. Поколения ЭВМ каждого периода отличаются друг от друга элементной базой и математическим обеспе чением. Первое поколение (1945-1954) - ЭВМ на электронных лампах. Их быстродействие не превышало 2—3 тыс. операций в секунду, оперативная память не превышала 2 Кб. Машинно-зависимые языки программирования низкого уровня – двоичные машинные коды, Автокод, языки Ассемблера.

Языки программирования

Год Язык (идея) Создатель

ЭВМ Заметки о языке

46 Плюнкалкюль

Цузе Z4 Немецкий инженер Цузе разработал этот язык для ЭВМ Z4, но ни компилятора, ни интерпретатора для него написано не было (поскольку и язык, и ЭВМ он разрабатывал в одиночку).

49 "Краткий код"

Мочли Юнивак

По своей сути, это была система обозначений для быстрого ввода в ЭВМ алгебраических выражений.

"Краткий код" работал как примитивный интерпретатор.

49 Идея подпрограммы

Грейс Хоппер

Марк-1 Программисты под руководством Хоппер впервые во всем мире реализовали идею подпрограмм как многократно используемую последовательность команд. Тогда они просто переписывали куски машинного кода друг у друга из блокнотов.

Языки программированияГо

дЯзык

(идея)Создате

льЭВМ Заметки о языке

50 Ассемблер Грейс Хоппер

Эдсак Первый ассемблер представлял из себя систему мнемонических обозначений, объединённую с библиотекой подпрограмм

52 АВТОКОД Гленн Марк-1 Автокод был первым полноценным транслятором (компилятором), т.е. он транслировал мнемоническую схему в машинные коды.

52 А-0 Грейс Хоппер

Юнивак

А-0 был первым полноценным ассемблером, получившим широкую известность. Он предоставлял услуги как компилятора, так и компоновщика.По сути, А-0 представлял первое

промышленное средство для создания других программ.

56 B-0 Грейс Хоппер

Юнивак

Хоппер создала первый ассемблер, который понимал мнемонические команды.

Второе поколение ЭВМ

ЭВМ 2-го поколения были разработаны в 1950—60 гг. В качестве основного элемента были использованы уже не электронные лампы, а полупроводниковые диоды и транзисторы, а в качестве устройств памяти стали применяться магнитные сердечники и магнитные барабаны - далекие предки современных жестких дисков. Второе отличие этих машин — это то, что появилась возможность программирования на алгоритмических языках. Были разработаны первые языки высокого уровня - Фортран, Алгол, Кобол.

Языки программирования

Год Язык (идея) Создатель

ЭВМ Заметки о языке

54 FORTRAN Бэкус IBM-704 Был первым языком программирования высокого уровня. Разрабатывался компанией IBM для её новой ЭВМ.

Коллектив под руководством Бэкуса разработал не только спецификацию языка, но и создал компилятор для него. Это обеспечило достаточно быструю и широкую распространенность языка.

Кроме того, Фортран был первым языком, для которого были разработаны компиляторы для разных ЭВМ (т.е. программа могла выполняться на различных ЭВМ).

Лучше всего Фортран подходит для решения инженерных и расчетных задач.

58 ALGOL – 58     Первая спецификация Алгола была рождена европейским международным комитетом.

59 “CSC” – первая компания по разработке ПО

    В 59 году в США появилась первая компания, занимающаяся созданием промышленных программ.

Языки программирования

Год Язык (идея) Создатель

ЭВМ Заметки о языке

59 БНФ Бэкус, Наур

  Для описания спецификации Алгола Бэкус создал специальную систему – “нормальную форму”. Чуть позже эта система была уточнена Науром.

59 CODASYL     Министерство обороны США создало организацию CODASYL, главным назначением которой было создание нового языка, ориентированного на бизнес – приложения.

60 ALGOL – 60 Бэкус   Новая спецификация Алгола, которую отличали следующие идеи:

Блочная структура Возможность рекурсии Описание с использованием БНФ

59 COBOL CODASYL   Стандарт языка, принятый для создания коммерческих приложений

58 Lisp Маккарти Язык для исследований в области искусственного интеллекта, предназначенный для работы со списками и лямбда – выражениями (был создан в МТИ).

Лекция №2

Эволюция языков программирования

(продолжение)

Программирование на языке высокого уровня

Третье поколение ЭВМ

Разработка в 60-х годах интегральных схем - целых устройств и узлов из десятков и сотен транзисторов, выполненных на одном кристалле полупроводника (то, что сейчас называют микросхемами) привело к созданию ЭВМ 3-го поколения. В это же время появляется полупроводниковая память, которая и по сей день используется в персональных компьютерах в качестве оперативной.

Языки программированияГод Язык (идея) Создател

ьЭВМ Заметки о языке

64 ПЛ/1 Рэдин (IBM)

  Универсальный язык программирования, разрабатывавшийся для системы System/360. Учитывая количество средств, которые были вложены в разработку и пропаганду этого языка и конечный результат, можно сказать, что этот проект провалился. Язык имел плохой дизайн.

64 БЭЙСИК Кемени, Курц

  Был разработан в Дартмундском колледже как язык для обучения работе с компьютером студентов всех специальностей (и технических, и гуманитарных). Начал разрабатываться в 59-60х годах, когда существовал только Фортран. Отличия от Фортрана:

o операторы ввода/вывода o единая система чисел (без различия на

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

Одновременно с разработкой языка велась разработка ЭВМ, которая работала бы не в пакетном режиме, а в режиме разделения времени (отсюда – необходимость операторов ввода. Позже появится и структурно-ориентированный стандарт TrueBASIC.

Языки программированияГод Язык (идея) Создатель ЭВМ Заметки о языке

67 Симула 67 Создан на основе Алгола 60 для целей имитационного моделирования. В нём впервые появилось понятие «класса». Но этот язык был неэффективен.

66 АЛГОЛ – W Хоар, Вирт   Новый стандарт языка, который был предложен Хоаром и Виртом как альтернатива существующей спецификации (буква W – от фамилии Вирт).

68 АЛГОЛ – 68     Этот вариант Алгола очень не понравился Вирту. Он как и PL/1 получился слишком большим. Кроме того имел очень сложное описание. Отсутствие реально работающих промышленных компиляторов для Алгола-68 только довершило ситуацию.

72 Smalltalk 72 язык, который изначально разрабатывался учёными для обучения детей, чтобы изучать их психологию. Именно он служит первым претендентом на звание первого объектно-ориентированного (ОО) ЯП, так как вся последующая терминология ОО подхода пошла именно оттуда.

Языки программированияГод Язык (идея) Создател

ьЭВМ Заметки о языке

68 Статья о структурном программировании

Дейкстра   В этой статье Дейкстра доказывал вредность оператора “GOTO” (т.к. он нарушает последовательность операторов) и показывал, что любая программа может быть написана с использованием 3-х структур:

Последовательность Альтернатива Повторение

69 AПЛ Кеннет Айверсон (IBM)

  Очень компактный универсальный язык программирования. Именно для этого языка была организация ACM открыла первую SIG(Software Interest Group).

70 ПАСКАЛЬ Никлаус Вирт

  Был разработан Виртом как противопоставление Алголу-68. Язык с высокой структурированностью. До сих пор – лучший язык для обучения программированию.

71 ФОРТ Чарльз Мур

  Самый компактный язык программирования.Обладает высокой степенью расширяемости.Первое промышленное применение –

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

Языки программирования

Год Язык (идея) Создатель

ЭВМ Заметки о языке

72 С Керниган, Ричи, Bell Lab.

  Язык был разработан для написания операционной системы UNIX. В рекламных целях UNIX в университетах распространялся почти бесплатно, вместе с UNIX’ом распространялся и С.

До сих пор С – один из лучших языков для системного программирования.

72 ПРОЛОГ Алан Колмери   Логический язык программирования, в котором

описываются факты и отношения между ними.

75 HOLWG Уайтекер   HOLWG – рабочая группа по управлением Уайтекера, была создана Пентагоном для получения языка, который мог бы использоваться на всех компьютерах министерства обороны США. Результатом в 79 году стал язык Ада.

79 АДА Жан Ихбиа   Универсальный язык программирования, был разработан по заказу МО США.

После создания вышло требование переписать все существующие приложения на Аде.

Языки программирования

Год Язык (идея) Создатель

ЭВМ Заметки о языке

72 С Керниган, Ричи, Bell Lab.

  Язык был разработан для написания операционной системы UNIX. В рекламных целях UNIX в университетах распространялся почти бесплатно, вместе с UNIX’ом распространялся и С.

До сих пор С – один из лучших языков для системного программирования.

72 ПРОЛОГ Алан Колмери   Логический язык программирования, в котором

описываются факты и отношения между ними.

75 HOLWG Уайтекер   HOLWG – рабочая группа по управлением Уайтекера, была создана Пентагоном для получения языка, который мог бы использоваться на всех компьютерах министерства обороны США. Результатом в 79 году стал язык Ада.

79 АДА Жан Ихбиа   Универсальный язык программирования, был разработан по заказу МО США.

После создания вышло требование переписать все существующие приложения на Аде.

Четвертое поколение ЭВМ

Обычно считается, что период с 1975 г. принадлежит компьютерам четвертого поколения. Их элементной базой стали большие интегральные схемы (БИС. В одном кристалле интегрировано до 100 тысяч элементов). Быстродействие этих машин составляло десятки млн. операций в секунду, а оперативная память достигла сотен Мб. Появились микропроцессоры (1971 г. фирма Intel), микро-ЭВМ и персональные ЭВМ. Стало возможным коммунальное использование мощности разных машин (соединение машин в единый вычислительный узел и работа с разделением времени).

Языки программирования

Год Язык (идея) Создатель

ЭВМ Заметки о языке

85 С++ Бьярн Страуструп

Объектно-ориентированное расширение языка С

86 Perl Ларри Уолл

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

87 Oberon Никлаус Вирт

Оберон отличается от Модулы-2 отсутствием многих необязательных конструкций; добавлены же в язык средства объектно-ориентированного программирования -- расширяемые записи. Оберон -- это самый простой универсальный язык.

Языки программирования

Год Язык (идея)

Создатель

ЭВМ Заметки о языке

91 Python Интерпретируемый объектно-ориентированный язык программирования. По структуре и области применения близок к Perl, однако менее распространен и более строг и логичен.

92 Oberon-2 Никлаус Вирт

В 1992 году были приняты расширения языка Оберон, предложенные Ханспетером Мёссенбёком. Расширенный язык получил название Оберон-2. Основное нововведение -- связанные с типами процедуры. Сейчас Оберон-2 является фактическим стандартом языка

95 Delphi

95 PHP Расмус Лердорф

Языки программирования

Год Язык (идея)

Создатель

ЭВМ Заметки о языке

96 Java Кен Арнольд, Джеймс Гослинг

Наследует синтаксис C и C++ и избавлен от некоторых неприятных черт последнего. Отличительной особенностью языка является компиляция в код некоей абстрактной машины, для которой затем пишется эмулятор (Java Virtual Machine) для реальных систем. Кроме того, в Java нет указателей и множественного наследования, что сильно повышает надежность программирования.

99 C#

Пятое поколение ЭВМ

ЭВМ пятого поколения — это ЭВМ будущего. Программа разработки, так называемого, пятого поколения ЭВМ была принята в Японии в 1982 г. Предполагалось, что к 1991 г. будут созданы принципиально новые компьютеры, ориентированные на решение задач искусственного интеллекта. С помощью языка Пролог и новшеств в конструкции компьютеров планировалось вплотную подойти к решению одной из основных задач этой ветви компьютерной науки - задачи хранения и обработки знаний. Коротко говоря, для компьютеров пятого поколения не пришлось бы писать программ, а достаточно было бы объяснить на "почти естественном" языке, что от них требуется.    Предполагается, что их элементной базой будут служить не СБИС, а созданные на их базе устройства с элементами искусственного интеллекта. Для увеличения памяти и быстродействия будут использоваться достижения оптоэлектроники и биопроцессоры.

Пятое поколение ЭВМ

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

Языки искусственного интеллекта

В качестве основных языков программирования в этом, пока неосуществленном, проекте предполагались языки искусственного интеллекта LISP и PROLOG.

Создателем языка LISP (1956-1959 гг.) является Джон Маккарти, которого называют отцом искусственного интеллекта. Именно он первым ввел термин "искусственный интеллект". Основным в языке LISP является понятие рекурсивно определенных функций. Доказано, что любой алгоритм может быть описан с помощью некоторого набора рекурсивных функций. Основные идеи этого языка были позже использованы в языке программирования для детей LOGO, разработанном в 70-е годы в Массачусетском технологическом институте под руководством Сэймура Пейперта. Подмножество языка LOGO, включающее команды для Черепашки, применяется при раннем обучении программированию.

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

Лекция №3

Понятие алгоритма

Язык программирования Turbo Pascal

Понятие алгоритма Слово «алгоритм» происходит от имени узбекского

математика Хорезми (по арабски ал - Хорезми), который в IX веке разработал правила 4-х арифметических действий над числами в десятичной системе счисления.

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

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

Свойства алгоритма

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

действий; определенностью - точностью, не оставляющей

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

результативностью - свойством приводить к искомому результату за конечное число действий (шагов);

Массовостью - пригодностью для решения задач из некоторого класса.

Пример

Дано X, Вычислить 3x2+6x+2. Допустимые операции - сложение и умножение 2-х чисел. Т.о. есть предпосылки для разработки алгоритма:

исходные данные - X; действия - сложение, умножение,

которое применительно к выражению 3x2+6x+2 дадут искомый результат.

Т.к. среди действий нет возведения в степень выражение необходимо записать в виде 3xx+6x+2.

Алгоритм

начало; вычислить XX, результат обозначить через Y; вычислить 34, результат обозначить через Z; вычислить 6X, результат обозначить через W; вычислить Z+W, результат обозначить через U; вычислить U+2, результат обозначить через S; конец;

Язык Pascal

Алгоритмический язык программирования высокого уровня

Разработан Никлаусом Виртом в 1970 году для обучения студентов программированию.

Хорошо структурированный язык с жестким контролем типов данных

Язык программирования

Алфавит Лексемы

Идентификаторы Константы Знаки операций и разделители Комментарии

Выражения Типы данных и операции Операторы Структура программы

Алфавит

Кодовая таблица ASCII 1) латинские буквы и символ

подчеркивания: ABC...Zabc...z_ 2) арабские цифры: 012...9 3) 22 специальных символа: +-*/=><.,:;@')(][}{#$^

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

Лексемы

1) Служебные (зарезервированные) слова. 2) Имена. Они вводятся для обозначения в программе переменных, констант, типов, процедур и функций. 3) Числа и символьные строки. 4) Знаки операций и разделители. Они формируются из одного или нескольких специальных символов. 5) Комментарии - произвольная последовательность символов (не обязательно из алфавита языка, то есть допускаются и русские буквы), заключенную в фигурные скобки { }.

Идентификаторы

Первый символ – латинская буква Остальные – латинские буквы,

цифры, символ подчеркивания Ограничение по длине

Правильные и неправильные идентификаторы

3Yfgh

V x

R_36%

Fgh23_

&A

Выражения

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

Записываются в соответствии с правилами использования операций

Правильные и неправильные выражения

A+B

Sin(x)*(2+y)

D(+2/)c

‘A’*2

Операторы

оператор процедуры - оператор присваивания - условный оператор - составной оператор - оператор варианта - оператор цикла с предусловием - оператор цикла с постусловием - оператор цикла с параметром - присоединения - пустой оператор

Оператор присваивания

Самым простым действием над переменной является занесение в нее величины соответствующего типа. Иногда говорят об этом, как о присвоении переменной конкретного значения. Такая команда (оператор) в общем виде выглядит на языке Паскаль следующим образом:     <Имя переменной>:=<Выражение>;

     Выражение, указанное справа от знака ":=", должно приводить к значению того же типа, какого и сама переменная, или типа, совместимого с переменной относительно команды присваивания. Например, переменной типа Real можно присвоить значение типа Integer или Word (впрочем, наоборот делать нельзя). Выражение будет сначала вычислено, затем, его результат будет положен в ячейки памяти, отведенные для переменной.

Структура программы

[Program <Имя программы>;][Uses <Имена подключаемых модулей>;][Label <Список меток>;][Const <Объявления констант>;][Type < Объявления типов>;][Var < Объявления переменных>;][<Раздел подпрограмм>]Begin [<Операторы>]End.

Пример программы

program Summa;var A,B,Sum : integer;begin Writе(’Введите два числа: ’); Readln(A,B); Sum :=А+В; Writеln(’Сумма равна ’,Sum); Writе(’Нажмите Enter’); Readln;end.

Лекция №4

Стандартные типы данных языка Turbo Pascal

Тип данных

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

Операции и их приоритет

У нарны е (- @ not)

М ультипликативны е (* / d iv and)

Аддитивны е (+ - m od or)

О перации отнош ения (< > <= >= = <> )

Б инарны е

О перации язы ка П аскаль

Объявление переменных

var

<имя переменной>:<имя типа1>;

<имя1>[,<имя2>,…]:<тип2>;

var

a,b:integer;

ch:char;

Стандартные типы данных

П орядковы е

Вещ ественны е

П росты е типы

С труктурированны е типы

Т ипы данны х язы ка П аскаль

Порядковые типы данных

С им вольны й

Ц елочисленны е типы

Л огический

П еречисление

Д иапазон

П орядковы е типы

Порядковые типы

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

Функция ORD(X)

Для целых типов функция ORD(X) возвращает само значение Х, т.е. ORD(X)=X для Х, принадлежащего любому целому типу. Применение ORD(X) к логическому, символьному и перечисляемому типам дает положительное целое число в диапазоне от 0 до 1(логический тип), от 0 до 255(символьный), от 0 до 65535(перечисляемый).

Функции PRED(X) и SUCC(X)

PRED (X) – возвращает предыдущее значение порядкового типа (значение, которое соответствует порядковому номеру ORD (X)-1) то есть

ORD(PRED(X))=ORD(X)-1

SUCC (X) - возвращает следующее значение порядкового типа, которое соответствует порядковому номеру ORD (X)+1 т.е.

ОRD(SUCC(X))=ORD(X)+1.

Пример

var

c: char;

begin

с:='5';

writeln(pred(c));

writeln(succ(c));

end.

Символьный тип

Значением символьного типа является множество всех символов ПК. Каждому символу приписывается целое число в диапазоне 0..255. Это число служит кодом внутреннего представления символа, его возвращает функция ORD.

Служебные коды (0..31)

Символ Код ЗначениеBel 7 ЗвонокLf 10 Перевод строки: при выводе на экран все

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

Cr 13 Возврат каретки (enter, при вводе означаеткоманду “ввод” и в буфер ввода не помещается;при выводе означает команду “продолжитьвывод с начала текущей строки”)

Sub 26 Конец файла: вводится с клавиатуры нажатиемctrl+Z

Esc 27 Конец работы: вводится с клавиатуры нажатиемна клавишу esc

Операции и функции

К типу CHAR применимы операции отношения, а также встроенные функции:

CHR (B) – функция типа CHAR преобразует выражение В типа BYTE в символ и возвращает его своим значением;

UPCASE (CH) – функция типа CHAR; возвращает символ в верхнем регистре, если он определен для аргумента CH типа CHAR, в противном случае возвращает сам символ Ch

Пример

Var c1,c2:char;

Begin

c1:=upcase('s');

c2:=upcase('ф');

Writeln (c1,' ', c2);

End.

Целочисленные типы

Длина, байт Названиетипа

Диапазонзначений

1 Byte 0..255

1 Shortint -128..127

2 Word 0..65535

2 Integer -32768..32767

4 Longint -2147483648..2147483647

Функции

Обращение Тип результата

Действие

Abs (x) X Возвращает модуль х Chr (b) Char Возвращает символ по его

коду Dec(vx[,i]) Процедура Уменьшает значение vx на

i, при отсутствии i -на 1 Inc(vx[,i]) Процедура Увеличивает значение vx

на i, при отсутствии i -на 1 Hi(i) Byte Возвращает старший байт

аргумента Hi(w) Byte То же

Функции

Lo (i) Byte Возвращает младший байтаргумента

Lo(w) Byte То жеOdd(l) Boolean Возвращает TRUE , если

аргумент нечетное число, False –если четное

Random(w) Как упараметра

Возвращает псевдослучайноечисло, равномернораспределенное на интервале0 <= х <w

Sqr(X) То же Возвращает квадрат аргумента

Swap(i) Integer Меняет местами байты в словеSwap(w) Word То же

Пример

Var

a: integer;

x, y: real;Begin

a:=32767;

x:= a+2;

y:=longint (a)+2;

Writeln (x:10:0,y:10:0);End.

Результат: -32767 32769

Целочисленное деление

a = (a div b)*b+(a mod b)

Лекция №5

Стандартные типы данных языка Turbo Pascal

(продолжение)

Логический тип

Значениями логического типа может быть одна из предварительно объявленных констант FALSE (ложь) или TRUE (истина). Для них справедливы правила:

Ord (false) = 0;

Ord (true)=1;

False<True;

Succ (False)=True;

Pred (true)=False;

Логические операции

A Not A

False True

True False

Логические операции

A B A and B

False False False

False True False

True False False

True True True

Логические операции

A B A or B

False False False

False True True

True False True

True True True

Логические операции

A B A xor B

False False False

False True True

True False True

True True False

Логические операции

if I mod 7 = 0 then

if I mod 13 = 0 then

writeln(I);

if (I mod 7 = 0) and (I mod 13 = 0) then

writeln(I);

Раздел описания типов

Раздел описания типов начинается ключевым словом Type и содержит описания новых типов данных, созданных программистом:

Type

<Имя типа1>=<Описание1>;

<Имя типа2>=<Описание2>;

...

Перечисляемый тип

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

Пример

tуре

TypeMonth=(jan,feb,mar,apr,may, jun,jul,aug,sep,oct,nov,dec);

Var

Month:TypeMonth;

...

If Month = aug then

writeln(’Лето!');

Тип диапазон

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

Тип-диапазон задается границами своих значений внутри базового типа:

<мин. знач.>..<макс. знач.>

Пример

Type

Digit = '0'..'9';

Dig2 = 48..57;

Var

Date: 1..31;

Month: 1..12;

Lchr:'A'..'Z';

D1:Digit;

Вещественные типы

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

Представление вещественных чисел

1.234560E+003 1234.56 0.123456E+004 0.123456*104

123456 0.123456*106

Вещественные типы

Длина, байты

Название типа

Мантисса Диапазон десятичного порядка

4 Single 7...8 -45...+38

6 Real 11...12 -39...+38

8 Double 15...16 -324...+308

10 Extended 19...20 -4951...+4932

8 Comp 19...20 -263+1...+263-1

Вещественные типы

Как видно из таблицы вещественное число в Паскале занимает от 4-х до 10 смежных байт и имеет следующую структуру в памяти ПК.

S E M

Здесь s-знаковый разряд числа; е – экспоненциальная часть, содержит двоичный порядок; m- мантисса числа.

Функции

Обращение

Тип параметра

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

Примечание

Abs(x) Real, integer

Тип аргумента Модуль аргумента

ArcTan(x) Real Real Арктангенс (радианы)

Cos (x) “ “ Косинус (радианы)

Exp (x) “ “ Экспонента

Frac (x) “ “ Дробная часть числа

Int (x) “ “ Целая часть числа

Ln (x) “ “ Логарифм натуральный

Pi - Real П = 3.141592653...

Функции

Обращение

Тип параметра

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

Примечание

Random - Real Равномерное псевдослучайное

число 0<=x<1

Random(i) Integer Integer Равномерное псевдослучайное

целое число 0<=x<i

Randomize - - Инициация датчика случайных чисел

Sin(x) Real Real Синус (радианы)

Sqr(x) Real, integer

Тип аргумента Квадрат аргумента

Sqrt (x) real Real Корень квадратный

Пример

var x, y: real;begin write(‘Введите значение x: ‘); readln(x); y:=(1+sin(2*x))/cos(2*x); writeln(‘Результат=’, y:10:3);end.

Лекция №5

Операторы языка Turbo Pascal

Составной оператор

Составной оператор – это последовательность произвольных операторов программы, заключенная в операторные скобки – зарезервированные слова begin…end. Составные операторы – важный инструмент Турбо Паскаля, дающий возможность писать программы по современной технологии структурного программирования (без операторов перехода goto).

Составной оператор Язык Турбо Паскаль не накладывает никаких

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

Begin ....... Begin ....... Begin ....... End; ....... End; .......End;

Пустой оператор

Фактически, весь раздел операторов, обрамленный словами begin…end, представляет собой один составной оператор. Поскольку зарезервированное слово end является закрывающей операторной скобкой, оно одновременно указывает и конец предыдущего оператора, поэтому ставить перед ним символ «;» необязательно.

Пустой оператор

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

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

Таким образом, условный оператор - это средство ветвления вычислительного процесса.

Условный оператор

Условный оператор

if <условие> then <оператор1> [else <оператор2>];

где if, then, else – зарезервированные слова (если, то, иначе); <условие> – произвольное выражение логического типа; <оператор1>, <оператор2>, – любые операторы языка Турбо Паскаль.

Алгоритм работы

Условный оператор работает по следующему алгоритму. Сначала вычисляется условное выражение <условие>. Если результат есть true (истина), то выполняется <оператор1>, а <оператор2> пропускается; если результат есть false (ложь), наоборот, <оператор1> пропускается, а выполняется <оператор2>.

Пример

var x, y, max : real; ....... if x>y then max:=x else max:=y;При выполнении этого фрагмента переменная max получит значение переменной x, если это значение больше чем значение y, в противном случае max станет равным y.

Пример

Часть else <оператор2> условного оператора может быть опущена. Тогда при значении true условного выражения выполняется <оператор1>, в противном случае этот оператор пропускается:var x, y, max : real; ....... if x>max then max:=x; y:=x;

Пример

Поскольку любой из операторов <оператор1> и <оператор2> может быть любого типа, в том числе и условным, а в то же время не каждый из «вложенных» условных операторов может иметь часть else <оператор2>, то возникает неоднозначность трактовки условий, т.е. непонятно какой else к какому if…then относится. Эта неоднозначность в Турбо Паскале решается следующим образом: любая встретившаяся часть else соответствует ближайшей к ней «сверху» части if…then условного оператора.

Примерvar a, b, c, d : integer;… a:=1; b:=2; c:=3; d:=4; if a>b then if c<d then if c<0 then c:=0 else a:=b; {a=1} if a>b then if c<d then if c<0 then c:=0 else else else a:=b; {a=2}

Использование составного оператора

Обратите внимание на то, что перед else точка с запятой не ставится. Символ «;» в Паскале означает конец оператора, а оператор if заканчивается там где заканчивается <оператор2> (если есть часть else).

В случае, когда необходимо выполнить несколько операторов, а не один (<оператор1> или <оператор2>) их необходимо заключить в операторные скобки begin … end, получив, тем самым, составной оператор.

if a>b then

begin

if c<d then

if c<0 then

c:=0;

end

else a:=b;

Program Hex;

var

n : Integer; {Вводимое число} 

ch : Char; {Результат} 

begin

Write ( 'n = ' ) ;

ReadLn(n); { Вводим число } 

{Проверяем число на принадлежность к диапазону 0...15}

if (n >= 0) and (n <= 15) then

begin {Да, принадлежит диапазону} 

if n < 10 then ch := chr(ord('0') +

n) else ch := chr(ord('A')

+ n- 10); WriteLn('n = ',ch)  end else {He принадлежит

диапазону} WriteLn('Ошибка')  end.

Пример

Оператор выбора Case

Если у вас не два возможных варианта выполнения программы, а больше, то может использоваться оператор выбора CASE. Структура этого оператора в Турбо Паскале:

CASE <ключ_выбора> OF C1 : <оператор1>; C2 : <оператор2>; . . . CN : <операторN>; [ELSE <оператор0>;]END;

Здесь <ключ_выбора> - это выражение порядкового типа, в зависимости от значения которого принимается решение; C1,...,CN - значения, с которыми сравнивается значение <ключа>; <оператор1>,..., <операторN> - оператор (возможно составные), из которых выполняется rnr, с константой которого происходит первое совпадение значения <ключа>, <оператор0> выполнится, если значение ключа не совпадает ни с одной из констант C1,...,CN.

Ветвь Else не обязательна, и в отличие от оператора if, перед ней можно ставить точку с запятой. Если для нескольких значений <ключа> действия совпадают, то эти константы можно перечислить через запятую перед двоеточием или даже задать диапазон значений (нижняя граница .. верхняя граница).

Program calc;Var a,b,rez:real; oper:char;Begin write(‘Введите два числа: ’); readln(a,b); write(‘Введите операцию: ‘); readln(oper); case oper of ‘+’:rez:=a+b; ‘-’:rez:=a-b; ‘*’:rez:=a*b; ‘/’:rez:=a/b; end; writeln(‘Результат=‘,rez);end.

Лекция №6

Операторы повтора (циклы)

Циклы

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

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

Цикл while («Пока»)

Первый вариант цикла называется циклом с предпроверкой условия или циклом "Пока" записывается следующим образом:

while <условие выполнения цикла> do

<оператор>; По-русски это можно прочитать так: "Пока

истинно условие, выполнять оператор". 

Алгоритм работы

Выполнение цикла начинается с проверки <условия выполнения цикла>. Если оно истинно, то выполняется <оператор> (тело цикла). Потом снова проверяется <условие выполнения цикла> и, если оно истинно, то выполняется <оператор> и т.д. Если на коком-то шаге <условие выполнения цикла> станет ложным, то выполнение цикла будет завершено. Таким образом, пока <условие выполнения цикла> истинно будет выполняться <оператор>. Если <условие выполнения цикла> изначально ложно, то <оператор> ни разу не будет выполнен.

Использование составного оператора

Если в цикле необходимо выполнить несколько операторов, то необходимо воспользоваться составным оператором:

while <условие выполнения цикла> do

begin <операторы>end;

Цикл repeat («Повторить»)

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

repeat

<операторы>;

until <условие выхода из цикла>;

Алгоритм работы

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

Использование составного оператора

Тело цикла может содержать несколько операторов, причем нет необходимости использовать составной оператор, поскольку в качестве операторных скобок здесь выступают ключевые слова repeat и until.

Зацикливание

Чтобы не произошло зацикливание программы, необходимо чтобы:

1. на момент начала выполнения цикла определены (имеют начальные значения) все переменные участвующие в вычислении значений условий и

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

Цикл for («С параметром»)

Следующий вариант оператора цикла включает в себя оба этих условия. и записывается следующим образом:

for <переменная цикла>:=<начальное значение> to <верхняя граница> do

<оператор>;

Алгоритм работы

Выполнение цикла начинается с присвоения <переменная цикла> <начального значения>. Далее, если значение <переменная цикла> меньше или равно значению <верхней границы>, то выполняется <оператор>. Потом значение переменной цикла увеличивается на единицу и снова проверяется условие, что значение <переменной цикла> меньше или равно значению <верхней границы>, выполняется <оператор> и т.д.

Шаг -1

Есть еще один вариант цикла for:for <переменная цикла>:=<начальное значение> downto <нижняя граница>

do <оператор>; Здесь на каждом шаге значение

переменной цикла уменьшается на единицу.

Примеры

Следующая маленькая программа выводит на экран кодовую таблицу:

Program Str3;Var

I : Byte;Begin For I:=32 to 255 do Write('VV',I:4, '-',Chr(I))End.      Цикл в программе начинается с 32 потому, что

символы с кодами от 0 до 31 являются управляющими и не имеют соответствующего графического представления.

Поиск совершенных чисел

Совершенными называются числа, равные сумме всех своих делителей, включая 1. Например, 6 – совершенное число, поскольку 6=1+2+3. Требуется найти и вывести на экран все совершенные числа вместе с их делителями, лежащие в диапазоне от 4 до 10000.

Var I,sum,del1,n:word;

Begin

for i:=4 to 10000 do

Begin

sum:=1; n:= trunc(sqrt(i));

for del1:=2 to n do

if I mod del1 =0 then

if del1<> I div del1 then begin

sum:=sum+del1+(I div del1);

end

else

sum:=sum+del1;

if sum=i then

writeln(i);

End;

End.

Вычислить квадратный корень

Вычислить квадратный корень из произвольного вещественного числа, введенного с клавиатуры, используя метод Ньютона:

Здесь A – введенное число, Y0=A. Если A – отрицательное число, то необходимо вывести

сообщение об ошибке. Результат должен иметь относительную точность 1·10-6.

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

nnn Y

AYY

2

11

61 101

nn YY

Var A,Y1,Y:real;Begin write(‘Введите число:’); readln(A); Y1:=A; repeat Y:=Y1; Y1:=(Y+A/Y)/2; until abs(Y1-Y)<0.000001; writeln(‘Корень из числа=‘,Y1:10:5);end.

Разбиение числа на цифры

X mod 10 X div 10000 (x mod 10000) div 1000 (x div 1000) mod 10 i*100+j*10+k

Вывод трехзначных чисел из неповторяющихся цифр

For i:=0 to 9 do for j:=0 to 9 do for k:=0 to 9 do if (i<>j)and(i<>k)and

(j<>k) then write(I,j,k,’ ‘);

Вывод чисел из нечетных цифр

i:=1;While i<=9 dobegin J:=1; while j<=9 do begin K:=1; while k<=9 do begin write(I,j,k,’ ‘); Inc(k,2); end; Inc(j,2); end; Inc(I,2);End;

Лекция №7

Массивы

Структурированные типы данных

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

Объявление переменной-массива

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

var

<имя переменной>:array[<тип индекса>] of <тип элемента>;

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

Примеры объявлений

Приведем пример переменной типа массив:

var

A: array[1..100] of Real;

B: array[char] of integer;

C: array[boolean] of char;

C[True]:=‘1’;

Доступ к элементам массива Конкретный элемент массива обозначается с

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

A[5]:=3.4;For i:=1 to 100 doBegin writeln(‘Введите элемент A[‘,I,’]:’); Readln(A[i]);End;

Сумма элементов массива

Const N=10; Var a:array[1..N] of real; i:word; sum:real; Begin sum:=0; for i:=1 to N do sum:=sum+a[i]; writeln(‘Сумма=‘,sum:10:5); end.

Const <имя конст.>=<значение>;

Произведение элементов массива

Const N=10; Var a:array[1..N] of real; i:word; p:real; Begin p:=1; for i:=1 to N do p:=p*a[i]; writeln(‘Произведение=‘,p:10:5); end.

randomize; for i:=1 to N do a[i]:=x1+random*(x2-x1);

b[1]:=1; b[2]:=1; for i:=3 to N do b[i]:=b[i-1]+b[i-2];

for i:=1 to N do if b[i] mod 2=0 then b[i]:=sqr(b[i]);

i:=2; while i<=N do begin a[i]:=sqr(a[i]); Inc(I,2); End;

Лекция №8

Многомерные массивы

Двумерные массивы

Если тип элемента в типе массив также является массивом, то результат можно рассматривать как массив массивов или как один многомерный массив. Например,

array[boolean] of array[1..10] of Real;

интерпретируется компилятором точно так же, как массив:

array[boolean,1..10] of Real;

В случае многомерного массива можно использовать несколько индексов или несколько выражений в индексе. Например:

Matrix[I][J] что тождественно записи:

Matrix[I,J]

For i:=1 to N do for j:=1 to M do begin writeln(‘Введите элемент a2[‘,I,’,’,j,’]: ‘);

readln(a2[I,j]); end;

For i:=1 to N do begin for j:=1 to M do write(a2[I,j]:8); writeln; end;

For i:=1 to N-1 do for j:=1 to N-i do begin tmp:=c2[I,j]; c2[I,j]:=c2[N-j+1,N-i+1]; c2[N-j+1,N-i+1]:=tmp; end;

Лекция №9

Процедуры и функции

Заголовок процедуры имеет вид: PROCEDURE <имя> [(<сп.ф.п.>)]; Заголовок функции: FUNCTION <имя> [(<сп.ф.п.>)] : <тип>; Здесь <имя> - имя подпрограммы (правильный

идентификатор); <сп.ф.п.> - список формальных параметров, <тип> - тип возвращаемого функцией результата. Список формальных параметров необязателен и

может отсутствовать. Если же он есть, то в нем должны быть перечислены имена формальных параметров и их тип, например:

Procedure SB (a: real; b: Integer; с: char);

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

Function F (а: real; b: real): real; можно написать проще: Function F (a, b: real): real;

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

Любой из формальных параметров подпрограммы может быть либо параметром-значением, либо параметром-переменной. В предыдущем примере параметры А и В определены как параметры-значения. Если параметры определяются как параметры-переменные, перед ними необходимо ставить зарезервированное слово VAR, например:

Function Power (var a : real; b : real) : real;

Здесь параметр А – параметр-переменная, а В – параметр-значение.

Определение формального параметра тем или иным способом существенно только для вызывающей программы: если формальный параметр объявлен как параметр-переменная, то при вызове подпрограммы ему должен соответствовать фактический параметр в виде переменной нужного типа; если формальный параметр объявлен как параметр-значение, то при вызове ему может соответствовать произвольное выражение.

В программе задаются два целых числа 5 и 7, эти числа передаются процедуре INC2, в которой они удваиваются. Один из параметров передается как параметр-переменная, другой - как параметр-значение. Значения параметров до и после вызова процедуры, а также результат их удвоения выводятся на экран.

const а : integer = 5; b : integer = 7;PROCEDURE lnc2 (var с : Integer; b : Integer);begin {Inc2} с := с + с; b := b + b; writeln(' удвоенные:', c:5, b:5);end; {Inc2}BEGIN {main} writeln(' исходные:'. a:5, b:5); lnc2(a,b); writeln(' результат:', a:5, b:5);END. {main}

В результате прогона программы будет выведено:

Исходные: 5 7 удвоенные 10 14 результат 10 7

Как видно из примера, удвоение второго формального параметра в процедуре INC2 не вызвало изменения фактической переменной В, так как этот параметр описан в заголовке процедуры как параметр-значение. Этот пример может служить еще и иллюстрацией механизма "закрывания" глобальной переменной одноименной локальной: хотя переменная В объявлена как глобальная (она описана в вызывающей программе перед описанием процедуры), в теле процедуры ее «закрыла» локальная пере менная В, объявленная как параметр-значение.

Формат описания процедуры:Procedure <Имя процедуры> (<Имя форм. параметра 1>:<Тип1>;< Имя форм. параметра 2>:<Тип2>); <Раздел описаний>Begin <Тело процедуры>End;

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

Формат описания функции:Function <Имя функции> (<Имя форм. параметра 1>:<Тип>;< Имя форм. параметра 2>:<Тип>?) : <Тип результата>;<Раздел описаний>Begin<Тело функции>End;

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

<Имя функции>:=<Выражение>;

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

Вызов процедуры представляет в программе самостоятельную инструкцию:

<Имя процедуры>(<Фактический параметр 1>, < Фактический параметр 2>,…);

Типы фактических параметров должны быть такими же, что и у соответсвующих им формальных.

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

Program Fn;VarA,B,C :Real;Function Max(A,B:Real):Real;

{Описываем функцию Max с формальными}Begin {параметрами A и B, которая принимает }

If A>B Then Max:=A {значение максимального из них }Else Max:=B

{Здесь A и B - локальные переменные }End;

BeginWriteln('Введите три числа');

Readln(A,B,C);Writeln('Максимальным из всех является ',

Max(Max(A,B),C))End.

Program Pr;VarS1,S2,S3 :Integer;Procedure Swap(Var A,B: Integer);{Процедура Swap с параметрами-переменными}Var C : Integer; {C - независимая локальная переменная}Begin C:=A; A:=B; B:=C {Меняем местами содержимое A и B}End;Begin

Writeln('Введите три числа');Readln(S1,S2,S3);If S1>S2 Then Swap(S1,S2);If S2>S3 Then Swap(S2,S3);If S1>S2 Then Swap(S1,S2);Writeln('Числа в порядке неубывания:V',S1,S2,S3)

End.

Рассмотрим следующий пример. В языке Турбо Паскаль нет операции возведения в степень, однако с помощью встроенных функций LN(X) и ЕХР(Х) нетрудно реализовать новую функцию с именем, например, POWER, осуществляющую возведение любого вещественного числа в любую вещественную степень. В следующем примере вводится пара чисел X и У и выводится на экран дисплея результат возведения Х сначала в степень +У, а затем - в степень - У. Для выхода из программы нужно ввести Ctrl-Z и «Ввод».

var х,у : real; FUNCTION Power(a,b : real) : real; begin {Power} if a > 0 then Power := exp(b * Ln(a)) else If a < 0 then Power := exp(b * Ln(abs(a))) else if b=0 then Power := 1 else Power := 0 end {Power}; BEGIN {main} repeat readln(x,y); writeln(power(x,y):12:10, power (x, -

у) :15:10) until EOF; END. {main}

Для вызова функции POWER мы просто указали ее в качестве параметра при обращении к встроенной процедуре WRITELN. Параметры Х и У в момент обращения к функции - это фактические параметры. Они подставляются вместо формальных параметров А и В в заголовке функции и затем над ними осуществляются нужные действия. Полученный резуль тат присваивается идентификатору функции - именно он и будет возвращен как значение функции при выходе из нее. В программе функция POWER вызывается дважды - сначала с параметрами Х и Y, а затем Х и ‑У, поэтому будут получены два разных результата.

Лекция №10

Строки

Тип STRING (строка) в Турбо Паскале широко используется для обработки текстов. Он во многом похож на одномерный массив символов ARRAY [0..N] OF CHAR, однако, в отличие от последнего, количество символов в строке-переменной может меняться от 0 до N, где N - максимальное количество символов в строке. Значение N определяется объяв лением типа STRING[N] и может быть любой константой порядкового типа, но не больше 255 . Турбо Паскаль разрешает не указывать N, в этом случае длина строки принимается максимально возможной, а именно N-255 .

Строка в Турбо Паскале трактуется как цепочка символов. К любому символу в строке можно обратиться точно так же, как к элементу одномер ного массива ARRAY [O..N] OF CHAR, например:

var st : string; if st[5] - 'A' then .. .

Самый первый байт в строке имеет индекс 0 и содержит текущую длину строки. Первый значащий символ строки занимает второй байт и имеет индекс 1. Над длиной строки можно осуществлять необходимые действия и таким способом изменять длину. Например, удалить из строки все ведомые пробелы можно следующим образом:

var st : strlng[10]; i : word; i := 10; while (st[l]=' ') and (i<>0) do begin dec(i): st[0] := chr(i) end; Значение ORD(st[0]) , т.е. текущую длину

строки, можно получить и с помощью функции LENGTH(st), например:

while ( Iength(st)<>0) and (st[ length(st)]-' ') do

s[0] := chr(length(st)-1) К строкам можно применять

операцию «+» - сцепление, например:

st := 'а' + 'b': st := st + 'с'; {st содержит 'abc'}

Если длина сцепленной строки превысит максимально допустимую длину N, то «лишние» символы отбрасываются. Следующая программа, например, напечатает символ 1:

var st:string[1]; begin st:='123'; writeln(st) end.

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

CONCAT(S1 [,S2, ... ,SN]) - функция типа STRING; возвращает строку, представляющую собой сцепление строк-параметров SI, S2,... ,SN.

COPY(ST, INDEX, COUNT) - функция типа STRING; копирует из строки ST COUNT символов, начиная с символа с номером INDEX.

DELETE(ST, INDEX, COUNT) - процедура; удаляет COUNT сим волов из строки ST, начиная с символа с номером INDEX.

INSERT(SUBST, ST, INDEX) - процедура; вставляет подстроку SUBST в строку ST, начиная с символа с номером INDEX.

LENGTH(ST) - функция типа INTEGER; возвращает длину строки ST.

POS(SUBST, ST) - функция типа INTEGER: отыскивает в строке ST первое вхождение подстроки SUBST и возвращает номер позиции, с которой она начинается; если подстрока не найдена, возвращается ноль.

STR(X [:WIDTH [:DECIMALS]], ST) - процедура; преобразует число Х любого вещественного или целого типов в строку символов ST так, как это делает процедура WRITELN перед выводом; параметры WIDTH и DECIMALS, если они присутствуют, задают формат преобразования:

WIDTH определяет общую ширину поля, выделенного под соответствующее символьное представление вещественного или целого числа X, а DECIMALS - количество символов в дробной части (имеет смысл только в том случае, когда Х - вещественное число).

VAL(ST, X, CODE) - процедура; преобразует строку символов ST во внутреннее представление целой или вещественной переменной X, которое определяется типом этой переменной; параметр CODE содержит ноль, если преобразование прошло успешно, и тогда в Х помещается результат преобразования, в противном случае он содержит номер позиции в строке ST. где обнаружен ошибочный символ, и в этом случае содержимое Х не меняется; ведущие пробелы в строке ST должны отсутствовать.

var х : real; у : Integer: st,st1: string; st:=concat('12','345'); {строка st содержит

12345} st1:=copy(st,3,length(st)-2); {st1 содержит 345} insert('-',st1,2); {строка st1 содержит 3-45} delete(st,pos{'2',st),3); {строка st содержит 12} str(pi:6:2,st); {строка st содержит 3.14) st1:='3,1415':

Сравнение строк

'Turbo' < 'Turbo Pascal' 'Паскаль' > 'Turbo Pascal'

Лекция №11

Записи

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

Структура объявления записи такова: <имя типа>= record <список полей> end; Здесь <имя типа> – правильный

идентификатор; record, end – зарезервированные слова; <список полей> – список полей;

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

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

Type

Birthday=record

day, month: byte;

year : word;

end;

var

a,b: Birthday;

...

В этом примере тип Birthday (день рождения) содержит три поля с именами day, month и year (день, месяц и год); переменные a, b сидержат записи типа Birthday.

Как и в массиве, значения переменных типа запись можно присваивать другим переменным того же типа, например

A:=b;

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

a.day:=27; b.year:=1939;

Для вложенных полей приходится продолжать уточнения:

var c: record name : string; bd : Birthday; end; ... if c.bd.year=1939 then ...

Оператор присоединения With

Если в программе содержится большое число обращений к компонентам записи (полям), то указание имени записи и имени поля с помощью сочленяющей точки будет громоздким . Для упрощения вводится оператор WITH - присоединение. Его еще называют оператором над записями:

WITH <имя переменной-записи> DO <оператор>; В этом случае, в операторе или составном операторе

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

Лекция №12

Создание новых типов данных на примере массива записей

Program students;Type stud=record fam,name:string[15]; group:integer; rating:real; end;Var kurs:array[1..N]of stud; oper:char; Begin repeat writeln(‘1-Добавить, 2-Удалить, 3-Просмотр, 0-Выход’); readln(oper); case oper of ‘1’:add; ‘2’:del; ‘3’:list; ‘0’:; else writeln(‘Ошибка, повторите ввод’); end; until oper=‘0’;end.

Лекция №13

Указатели

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

Когда вы описываете в Turbo Pascal глобальные переменные, компилятор выделяет для них память в области, которая называется сегментом данных. Сегмент данных имеет максимальный размер 64К. Это означает, что общий объем всех ваших глобальных переменных не может превышать 64К. Для многих программ этот предел значения не имеет, но в некоторых случаях вам может потребоваться больший объем.

Примечание: Локальные переменные не помещаются в сегмент данных и в пределе 64К не учитываются.

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

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

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

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

Указатель

Указатель - это какой-либо адрес в памяти вашего компьютера. Это может быть адрес переменной, записи данных, либо процедуры или функции. Обычно вам не важно, где расположен элемент в памяти. Вы можете просто ссылаться на него по имени, и Turbo Pascal знает, где его нужно искать.

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

Операция @

var SomeNumber: Integer; Вам не нужно беспокоиться о том, где

SomeNumber находится в памяти. Именно для этого задается имя.

Адрес размещения SomeNumber в памяти можно найти с помощью операции @. @SomeNumber - это адрес вашей целочисленной переменной. Вы можете присвоить этот адрес переменной-указателю, то есть переменной, содержащей адрес данных или кода в памяти.

Ссылочный тип

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

var SomeNumber: Integer; SomeAddress: Pointer; begin SomeNumber := 17; {присвоить SomeNumber

значение} SomeAddress := @SomeNumber; {присвоить

SomeAddress адрес} SomeAddress := Addr(SomeNumber); {другой способ

получения адреса} end.

Обычно вы определяете ссылочные типы, которые указывают на конкретный вид элемента, например, целое значение или запись данных. Как вы далее увидите, можно извлечь преимущество из того факта, что указателю известно, на что он указывает. Чтобы определить типизированный указатель, вы можете описать новый тип, определенный символом каре (^), за которым следуют один или более идентификаторов. Например, чтобы определить указатель на Integer, вы можете сделать следующее:

type PIneger = ^Integer;

Теперь вы можете описать переменные типа PInteger. Если вы не собираетесь часто использовать ссылочный тип, то можете просто описать переменные, как указатели на уже определенный тип. Например, если вы определили PInteger как ^Integer, то следующие описания переменной эквивалентны:

var X: ^Integer: Y: PInteger;

Разыменование указателей До сих пор мы видели, как можно

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

type PInteger = ^Integer; var SomeNumber: Integer; { присвоить

SomeNumber 17 } SomeAddress := @SomeNumber;

{ SomeAddress указывает на SomeNumber }

Writeln(SomeNumber); { напечатать 17 }

Writeln(SomeAddress); { не допускается; указатели печатать нельзя }

Writeln(SomeAddress^); { напечатать 17 }

AnotherAddress := SomeAddress; { также указывает на SomeNumber }

AnotehrAddress^ := 99; { новое значение для SomeNumber }

Writeln(SomeNumber); { напечатать 99 }

end.

Одним из наиболее важных моментов использования указателей является распределение динамических переменных в динамически распределяемой области памяти. Turbo Pascal предусматривает два способа выделения для указателя памяти: процедура New и процедура GetMem.

New - это очень простая процедура. После описания переменной-указателя вы можете вызвать процедуру New для выделения пространства в динамически распределяемой памяти для указываемого переменной элемента. Приведем пример:

var IntPointer: ^Integer; StringPointer: ^String; begin New(IntPointer); { выделяет в динамически распреде- ляемой области два байта } New(StringPointer); { выделяет в динамически распреде- . ляемой области 256 байт } . . end.

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

Dispose(StringPointer); Dispose(IntPointer);

GetMem, FreeMem, SizeOf

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

GetMem(<указатель>,<кол-во байтов>); Освобождение памяти в этом случае

производится с помощью процедуры FreeMem(<указатель>,<кол-во байтов>); Выделение памяти с использованием

функции SizeOf: GetMem((<указатель>, SizeOf((<тип>));

Лекция №14

Параметры процедур и функций

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

Procedure S (a : array (1..10] of real);

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

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

type atype = array [1..10] of real; PROCEDURE S (a : atype);

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

type intype = string[15]; outype = string[30]; FUNCTION St (s : intype) : outype;

Лекция №15

Работа с тестовыми файлами

Под файлом понимается либо именованная область внешней памяти ПК (жесткого диска, гибкой дискеты, электронного «виртуального» дис ка), либо логическое устройство – потенциальный источник или приемник информации.

Любой файл имеет три характерные особенности. Во-первых, у него есть имя, что дает возможность программе работать одновременно с не сколькими файлами. Во-вторых, он содержит компоненты одного типа. Типом компонентов может быть любой тип Турбо Паскаля, кроме файлов. Иными словами, нельзя создать «файл файлов». В-третьих, длина вновь создаваемого файла никак не оговаривается при его объявлении и ограни чивается только емкостью устройств внешней памяти.

Файловый тип или переменную файлового типа можно задать одним из трех способов:

<имя> = FILE OF <mun>; <имя> = TEXT: <имя> = FILE; Здесь <имя> - имя файлового типа (правильный

идентификатор); FILE, OF - зарезервированные слова (файл, из); TEXT - имя стандартного типа текстовых файлов; <тип> - любой тип Турбо Паскаля, кроме файлов.

В зависимости от способа объявления можно выделить три вида файлов:типизированные файлы (задаются

предложением FILE OF...);текстовые файлы (определяются

типом TEXT);нетипизированные файлы

(определяются типом FILE).

type product = record name string; соde : word; cost : comp; end; text80 = file of string[80]; var f1 : file of char; f2 : text; f3 : file; f4 : text80; f5 : file of product;

В наших примерах FI, F4 и F5 - типизированные файлы, F2 -текстовый файл, F3 - нетипизированный файл. Вид файла, вообще гово ря, определяет способ хранения информации в файле. Однако в Турбо Паскале нет средств контроля вида ранее созданных файлов. При объяв лении уже существующих файлов программист должен сам следить за соответствием вида объявления характеру файла.

Любой программе доступны два предварительно объявленных файла со стандартными файловыми переменными: INPUT - для чтения данных с клавиатуры и OUTPUT - для вывода на экран. Стандартный Паскаль требует обязательного упоминания этих файлов в заголовке программы, например, так

PROGRAM NameOfProfgram( input, output); В Турбо Паскале это необязательно, вот почему

заголовок програм мы можно опускать.

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

ASSIGN (<ф.п.>, <имя файла или, л.у.>); Здесь <ф.п.> - файловая переменная

(правильный идентификатор, объявленный в программе как переменная файлового типа);

<имя файла или л.у.> - текстовое выражение, содержащее имя фай ла или логическое устройство.

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

Для чтения файл инициируется с помощью стандартной процедуры RESET:

RESET (<ф. п.>); Здесь <ф.п.> - файловая переменная, связанная

ранее процедурой ASSIGN с уже существующим файлом или логическим устройством-при емником информации.

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

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

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

var f : file of char; assign(f,'myfile.dat'); {$I-} {Отключить контроль ошибок ввода-вывода} reset(f): {SI+} {Включить контроль ошибок ввода-вывода) If IOResult о 0 then ..... {Файл не существует} else ..... {Файл существует}

Стандартная процедура REWRITE (<ф.п.>) инициирует запись ин формации в файл или в логическое устройство, связанное ранее с файло вой переменной <ф. п. >. Процедурой REWRITE нельзя инициировать за пись информации в ранее существовавший дисковый файл: при выполне нии этой процедуры старый файл уничтожается и никаких сообщений об этом в программу не передается. Новый файл подготавливается к приему информации и его указатель принимает значение 0.

Стандартная процедура APPEND (<ф.п.>) инициирует запись в ра нее существовавший текстовый файл для его расширения, при этом ука затель файла устанавливается в его конец. Процедура APPEND приме нима только к текстовым файлам, т.е. их файловая переменная должна иметь тип TEXT (см. выше). Процедурой APPEND нельзя инициировать запись в типизированный или нетипизированный файл. Если текстовый файл ранее уже был открыт с помощью RESET или REWRITE, исполь зование процедуры APPEND приведет к закрытию этого файла и откры тию его вновь, но уже для добавления записей.

Процедура CLOSE. Закрывает файл, однако связь файловой пере менной с именем файла, установленная ранее процедурой ASSIGN, со храняется. Формат обращения:

CLOSE (<ф.п.>) При создании нового или расширении

старого файла процедура обеспечивает сохранение в файле всех новых записей и регистрацию файла в каталоге.

Текстовый файл трактуется в Турбо Паскале как совокупность строк переменной длины. Доступ к каждой строке возможен лишь последова тельно, начиная с первой. При создании текстового файла в конце каждой записи (строки) ставится специальный признак EOLN (End Of LiNe -конец строки). а в конце всего файла - признак EOF (End Of File - конец файла). Эти признаки можно протестировать одноименными логически ми функциями (см. ниже).

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

EOLN - последовательность кодов ASCII 13 (CR) и 10 (LF);

EOF - код 26 стандарта ASCII. Для доступа к записям применяются

процедуры READ, READLN, WRITE, WRITELN.

Процедура READ. Обеспечивает ввод символов, строки чисел. Фор мат обращения:

READ (<ф.п.>,<сп.ввода>); или READ (<сп.ввода>); Здесь <сп.ввода> - список ввода:

последовательность из одной или более переменных типа CHAR, STRING, а также любого целого или вещественного типа.

При вводе переменных типа STRING количество считанных проце дурой и помещенных в строку символов равно максимальной длине стро ки, если только раньше не встретились символы CR или EOF. В этом случае сами символы CR и EOF в строку не помещаются. Если количество символов во входном потоке данных больше максимальной длины строки, «лишние» символы до конца строки отбрасываются, а новое обращение к READ возвращает пустую строку.

При вводе числовых переменных процедура READ вначале выделя ет подстроку во входном потоке по следующему правилу: все ведущие пробелы, символы табуляции и маркеры конца строк EOLN пропускают ся; после выделения первого значащего символа, наоборот, любой из пе речисленных символов или символ EOF служат признаком конца под строки. Выделенная таким образом подстрока затем рассматривается как символьное представление числовой константы соответствующего типа и преобразуется во внутреннее представление, а полученное значение присваивается переменной. Если в подстроке был нарушен требуемый формат представления численной константы, возникает ошибка ввода-вывода.

const N = 1000; { максимальная длина ввода } var f : text; m : array [1..N] of real; i : Integer; BEGIN assign(f, 'prog.dat'); reset(f); i := 1; while not EOF(f) and (I <= N) do begin read(f,m[i]); inc(i); end; сlоse(f); end.

Процедура READLN. Обеспечивает ввод символов, строк и чисел. Эта процедура идентична процедуре READ за исключением того, что после считывания последней переменной оставшаяся часть строки до мар кера EOLN пропускается, поэтому следующее обращение к READLN или READ начинается с первого символа новой строки. Кроме того, эту про цедуру можно вызвать без параметра <сп.ввода> (см. процедуру READ), что приведет к пропуску всех символов текущей строки вплоть до EOLN.

Процедура WRITE. Обеспечивает вывод информации в текстовый файл или передачу ее на логическое устройство. Формат обращения:

WRITE(<ф.п.>,<сп.вывода>) или WRITE(<сп.вывода>);

Здесь <сп.вывода> - список вывода: последовательность из одного или более выражений типа CHAR, STRING, BOOLEAN, а также любого целого или вещественного типа.

Лекция №16

Типизированные и нетипизированные файлы

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

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

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

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

READ (<ф.п.>,<сп.ввода>); Здесь <сп.ввода> - список ввода,

содержащий одну или более переменных такого же типа, что и компоненты файла.

Файловая переменная <ф. п. > должна быть объявлена предложением FILE OF... и связана с именем файла процедурой ASSIGN. Файл необ ходимо открыть процедурой RESET. Если файл исчерпан, обращение к READ вызовет ошибку ввода-вывода.

Процедура WRITE. Используется для записи данных в типизиро ванный файл. Формат обращения:

WRITE (<ф.п.>,<сп.вывода>); Здесь <сп. вывода> - список

вывода, содержащий одно или более выражений того же типа, что и компоненты файла.

Процедура SEEK. Смещает указатель файла к требуемому компо ненту. Формат обращения:

SEEK (<ф. п. >,<N компонента>); Здесь <N компонента> - выражение типа

LONGINT, указывающее номер компонента файла.

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

Функция FILESIZE. Возвращает значение типа LONGINT, которое содержит количество компонентов файла. Формат обращения:

FILESIZE(<ф.п.>); Функцию нельзя использовать для

текстовых файлов. Чтобы пере местить указатель в конец

файла, можно написать: seek(FileVar, FileSize(FileVar)); где FILEVAR - файловая переменная.

Функция FILEPOS. Возвращает значение типа LONGINT, содер жащее порядковый номер компонента файла, который будет обрабаты ваться следующей операцией ввода-вывода. Формат обращения:

FILEPOS(<ф.п.>); Функцию нельзя использовать для

текстовых файлов. Первый ком понент файла имеет порядковый номер 0.

Нетипизированные файлы

Нетипизированные файлы объявляются как файловые переменные типа FILE и отличаются тем, что для них не указан тип компонентов. Отсутствие типа делает эти файлы, с одной стороны, совместимыми с любыми другими файлами, а с другой - позволяет организовать высоко скоростной обмен данными между диском и памятью.

При инициации нетипизированного файла процедурами RESET или REWRITE можно указать длину записи нетипизированного файла в байтах. Например, так:

var f : file; .......... assign(f, 'myfile.dat'); reset(f,5l2);

Длина записи нетипизированного файла указывается вторым параметром при обращении к процедурам RESET или REWRITE, в качестве которого может использоваться выражение типа WORD. Если длина за писи не указана, она принимается равной 128 байтам.

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

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

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

BLOCKREAD(<ф.п.>,<буф>,<N>[,<NN>]); BLOCKWRITE(<ф.п.>,<буф>,<N>[,<NN>]);

Здесь <буф> - буфер: имя переменной, которая будет участвовать в обмене данными с дисками;

<N> - количество записей, которые должны быть прочитаны или записаны за одно обращение к диску;

<NN> - необязательный параметр, содержащий при выходе из про цедуры количество фактически обработанных записей.

Лекция №17

Множества

Множества

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

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

Пример type DigitChar = set of '0'..'9'; Digit = set of 0..9; var s1,s2,s3: DigitChar; s4,s5,s6: Digit; ... s1:=['1','2','3']; s2:=['3','2','1']; s1:=['2','3']; s1:=[0..3,6]; s1:=[4,5]; s1:=[3..9]; ...

В этом примере множества s1 и s2 эквивалентны, а множество s3 включено в s2, но не эквивалентно ему.

Описание типа множество имеет вид<имя типа> = set of <базовый тип>;

Здесь <имя типа> – правильный идентификатор;set, of – зарезервированные слова (множество,

из);<базовый тип> – базовый тип элементов

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

Для задания множества используется так называемый конструктор множества: список спецификаций элементов множества, отделяемых друг от друга запятыми; список обрамляется квадратными скобками. Спецификациями элементов могут быть константы или выражения базового типа, а также – тип-диапазон того же базового типа.

Операции

Над множествами определены следующие операции:

* – пересечение множеств; результат содержит элементы, общие для обоих множеств. Например, s4*s6 содержит [3], s4*s5 – пустое множество.

+ – объединение множеств; результат содержит элементы из первого множества дополненные недостающими элементами из второго множества:

s4+s5 содержит [0,1,2,3,4,5,6];s5+s6 содержит [3,4,5,6,7,8,9];

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

s6-s5 содержит [3,6,7,8,9]; s4-s5 содержит [0,1,2,3,6];

= – проверка эквивалентности; возвращает true, если множества эквивалентны.

<> – проверка неэквивалентности; возвращает true, если множества неэквивалентны.

<= – проверка вхождения; возвращает true, если первое множество является подмножеством второго.

>= – проверка вхождения; возвращает true, если второе множество является подмножеством первого.

in – проверка принадлежности; в этой бинарной операции первый элемент – выражение, а второй – множество того же типа; возвращает true, если выражение имеет значение, принадлежащее множеству:

3 in s6 возвращает true; 2*2 in s1 возвращает false;

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

const N = 100; {Количество элементов исходного множества} type SetOfNumber = set of 1..N:var n1,next,i : word; {Вспомогательные переменные} BeginSet, {Исходное множество} PrimerSet : SetOfNumber; {Множество простых чисел}

BEGIN BeginSet := [2..N]; {Создать исходное множество} PrimerSet := [1]; {Первое простое число} Next := 2; {Следующее простое число} while BeginSet <> [] do {Начало основного цикла} begin n1:= next; {n1-число,кратное очередному

простому (next)} while n1 <- N do {Цикл удаления из исходного множества

непростых чисел:}

begin BeginSet := BeginSet-[n1]; n1 :=n1+next; {Следующее кратное} end; {Конец цикла удаления} PrimerSet := PrimerSet+[next]; repeat {Получить следующее простое, которое есть

первое невычеркнутое из исходного множества} inc(next) until (next In BeginSet) or (next > N) end; {Конец основного цикла)

{ Вывод результата: }

for i := 1 to N do

if I in PrimerSet then write(i:8);

writeln;

END.