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

ФЕДЕРАЛЬНОЕ АГЕНСТВО ПО ОБРАЗОВАНИЮ
РОССИЙСКОЙ ФЕДЕРАЦИИ

Московский государственный горный университет

Кафедра «Системы автоматизированного проектирования»

КАРПОВИЧ Е. Е.

Утверждено УМС МГГУ
в качестве учебного пособия

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

Учебное пособие

Для студентов специальности САПР вечернего отделения

Москва-2005

  УДК 681.142.2(075.8)  

Предмет информатики как науки

Информационная технология характеризуется следующими свойствами: · предметом (объектом) обработки являются данные; · цель процесса обработки – получение информации;

Техническое и программное обеспечение ПЭВМ

Структура аппаратных средств ПЭВМ

Персональная ЭВМ–это комплекс программных и аппаратных средств, предназначенных для автоматической обработки информации. ПЭВМ …   Рассмотрим структурную схему аппаратных средств ПЭВМ (см. рис 2.1), назначение устройств и принципы их…

Программное обеспечение ПЭВМ

Назначением ЭВМ является выполнение программ. Совокупность программ для персонального компьютера называется программным обеспечением (ПО). ПО ПЭВМ… § системное программное обеспечение – совокупность программ и программных… § инструментарий технологии программирования – набор программ и программных комплексов для разработки, отладки и…

Основы алгоритмизации

Этапы разработки программ

Разработка программ включает в себя следующие этапы: 1. Анализ и уточнение требований, предъявляемых к программе. Иногда этот этап… 2. Проектирование алгоритма и выбор структур данных (или алгоритмизация).

Формы представления алгоритмов

Ключевым этапом разработки программы является этап разработки алгоритма и структур данных. Результат этого этапа – формализованное описание или… Известны следующие формы представления алгоритмов: Ø словесное описание последовательности шагов обработки данных и условий их выполнения на естественном языке; …

Табл. 3.1.

 

Обозначение Назначение Примеры
 
 
 

 


Символ Процесс

 

    Блок вычислений и обработки данных
I=J+2

    Символ Решение       Блок проверки условия
  Символ Модификация       Блок организации и начала цикла

Табл. 3.1(продолжение).

 

Обозначение Назначение Примеры
 
       
 
 
   

 


Символ Пуск

  Блок начала алгоритма  
 
 
 

 


Символ Останов

  Блок конца алгоритма  
    Символ Ввод-вывод   Блок ввода-вывода информации
 
 
 

 

 


Символ Вызов

    Блок вычислений по стандартной или отдельно разработанной подпрограмме
  Символ Детализация   Блок, определяю-щий часть алгорит-ма, требующую дальнейшей детализации
  Проверка исходных данных  


Табл. 3.1(продолжение).

 

Обозначение Назначение Примеры
      Символ Соединитель   Разрыв линии потока управления, Перенос части блок-схемы на другую страницу  

 

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

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

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

Рассмотрим правила описания данных. Обрабатываемые алгоритмами данные характеризуются структурой, типом и назначением. Назначение данных определяет смысловое содержание данных, свойства реальных объектов, являющихся предметом данной задачи. По своему назначению данные делятся на три категории: входные данные, выходные данные и промежуточные данные задачи (алгоритма). Тип данных определяет набор допустимых значений и форму представления данных задачи в ЭВМ. По своему типу данные делятся на арифметические (числовые), символьные и логические. Эти типы данных называются базовыми или стандартными. Структура данных определяет способ объединения данных базовых типов. В алгоритмах используются следующие структуры данных: скаляры, массивы и записи. Скаляр – это именованная структура данных, содержащая неделимую единицу данных. В алгоритмах и программах являются простые переменные и константы.

Константы – это данные, которые при выполнении алгоритма (программы) всегда определены и неизменны. Переменные - это имена данных, которые в процессе выполнения программы могут изменять свое значение. В описании алгоритма на псевдокоде скалярные данные объявляются с помощью ключевого слова СКАЛЯР.

Массив - это упорядоченный набор однотипных переменных (элементов массива), объединенных общим именем и отличающихся номерами (индексами). С другой стороны, массив – это область памяти, в которой могут размещаться совокупности данных одного и того же типа. На псевдокоде массивы объявляются с помощью ключевого слова МАССИВ.

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

Запись – это именованная совокупность элементов различных типов. На псевдокоде записи объявляются с помощью ключевого слова ЗАПИСЬ. Доступ к элементам записи осуществляется по составному имени, включающему имя записи и имя элемента.

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

Алгоритм <название>

Входные данные:

< объявления >

Выходные данные:

< объявления >

Промежуточные данные:

< объявления >

Начало

<последовательность действий>

Конец

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

- операция присваивания значения переменной:

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

где <выражение> - либо другая переменная, либо константа, либо формула, значение которой должно быть вычислено и присвоено переменной, указанной слева от знака := (присвоить). Например,

A:=5;

B:= C/sin(alfa);

D:=D+1.

- операция ввода/вывода:

ввод(<список ввода>)

где <список ввода> - список переменных, значения которых должны вводиться;

вывод(<список выражений>)

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

ввод(A,B,C);

вывод(‘A= ‘,A).

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

· следование;

· разветвление;

· цикл.

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

 

<действие 1>

<действие 2>

 

Блок-схема структуры «Следование» показана на рис. 3.2.

 

       
 
 
   
Рис 3.2

 


Структура «Разветвление» обеспечивает выбор одного из двух альтернативных действий, в зависимости от того, выполняется или не выполняется некоторое условие, и на псевдокоде записывается следующим образом:

 

ЕСЛИ <условие> ТО

<действие 1>

ИНАЧЕ

<действие 2>

КОНЕЦ_ЕСЛИ

Блок-схема структуры «Разветвление» показана на рис. 3.3.


 

 
 

 

 


 
 

 


Рис. 3.3

 

 

На рис. 3.3 показано, что действие 1 выполняется, если выполняется условие, действие 2 выполняется, если условие не выполняется. После выполнения одного из двух действий, осуществляется переход на алгоритмическую операцию и структуру, следующую за структурой «Разветвление».

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

ЕСЛИ <условие> ТО

<действие >

КОНЕЦ_ЕСЛИ

Блок-схема сокращенной структуры «Разветвление» показана на рис. 3.4.

 

 
 

 

 


Обобщением структуры «Разветвление» является структура «Множественный выбор» :

ВЫБОР ПО <Var>

ЕСЛИ Var=Const1 ТО <действие 1 >

ЕСЛИ Var=Const2 ТО <действие 2 >

…………

ЕСЛИ Var=Constn ТО <действие n >

ИНАЧЕ <действие >

КОНЕЦ_ВЫБОР

В зависимости от значения переменной Var выполняется одно из указанных действий. Блок-схема структуры «Выбор» показана на рис. 3.5.

 

 

 


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

Различаются следующие типы структуры «Цикл»:

v цикл «ОТ ДО»;

v цикл «ПОКА» с предусловием и с постусловием;

v цикл «ДО».

Цикл «ОТ ДО» называется циклом с заданным числом повторений. Этот цикл управляет повторением выполнения действия с помощью переменной цикла:

ЦИКЛ ОТ I= N1 ДО N2 ШАГ <N3>

<действие>

КОНЕЦ_ЦИКЛА

где I – параметр цикла;

N1 – начальное значение параметра цикла;

N2 – конечное значение параметра цикла;

N3 – шаг изменения значения параметра цикла.

Значения N1, N2, N3 вычисляются один раз при входе в цикл. Переменная I принимает значения от N1 до N2, N3 = 1 (по умолчанию). Когда значение I становится больше N2, происходит выход из цикла. Блок-схема цикла «ОТ-ДО» показана на рис. 3.6.

       
 
 
   
Рис. 3.6

 

 


Блок-схема, показанная на рис. 3.6, может быть представлена с помощью графического символа «Модификация» (см. рис. 3.7).

 

 

 

   
 
 
 

 

 


Цикл «ПОКА» называется циклом с выходом по условию с предусловием, так условие продолжения повторяющихся действий перед выполнением очередной итерации:

 

ЦИКЛ ПОКА <условие>

<действие>

КОНЕЦ_ЦИКЛА

 

Блок-схема цикла «ПОКА» показана на рис. 3.8.

       
 
   
Рис. 3.8
 

 


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

Цикл «ДО» называется итерационным циклом с постусловием, так как условие выхода из цикла проверяется после выполнения действия, указанного в цикле:

 

ЦИКЛ

<действие>

ДО <условие>

 

Блок-схема цикла «ДО» показана на рис. 3.9.

 

 

 
 

 

 


До тех пор, пока условие не выполняется, указанное действие будет повторяться. Если условие выполняется, то происходит выход из цикла.

 

Классификация и примеры алгоритмических структур

 

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

- алгоритмы линейной структуры;

- алгоритмы разветвляющейся структуры;

- алгоритмы циклической структуры.

Рассмотрим на примерах различные типы алгоритмов.

 

Алгоритм линейной структуры.

Заданы радиусы оснований R1 и R2, длина образующей L и высота h прямого усеченного конуса. Найти площадь поверхности и объем усеченного конуса.   Постановка задачи.

Вывод V,S

 
 


       
   
Рис 3.10  
 
 

 

 

Алгоритм разветвляющейся структуры.

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

Ввод (X)

3.2.3. Алгоритмы циклической структуры.   Пример 1. Определить сумму заданного числа членов последовательности: 1, 1/4, 1/9, …… 1/n2.

Ввод(K)

    Вывод(S)

Ввод(R)

    Вывод(N)

Ввод(R)

       
   
 
 

 

 


Вывод(N)

 

 

Основы языка программирования Паскаль

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

Язык Паскаль, как и любой язык программирования имеет свой алфавит, синтаксис и семантику. Алфавит ¾ это набор допустимых в языке символов.… Алфавит языка Паскаль является подмножеством набора символов кода ASCII и… § прописные и строчные буквы латинского алфавита и символ подчеркивания;

Структура программы на языке Паскаль

Паскаль-программа включает в себя следующие разделы: § заголовок программы (Program); § раздел указания используемых модулей (Uses);

Табл. 4.2. Вещественные типы данных.

Описатель Диапазон Максимальное количество значимых цифр мантиссы Размер в байтах
Single от 1.5 x 10-45 до 3.4x 1038
Real от 2.9 x 10-39 до 1.7x 1038
Double от 5.0 x 10-324 до 1.7x 10308
Extended от 3.4 x 10-4932 до 1.1x 104932
Comp от -9.2 x 1018 до 9.2x 1018

 

Наиболее употребительными являются типы Real и Double. Для работы с типами данных Single, Double Extended и Comp необходимо включать директиву компилятора {$E+}, которая подключает специальные программы для выполнения арифметических действий. При использовании типа Real эта директива не нужна.

 

Стандартный логический тип Boolean, размер которого 1 байт, представляет собой тип данных, любой элемент которого может принимать лишь одно из двух значений: True (истина) и False (ложь). True > False.

В Borland Pascal 7.0 добавлены еще три логических типа: ByteBool (1 байт), WordBool (2 байта), LongBool (4 байта) для совместимости с языком C++ и ОС MS Windows. Для типа Boolean значению True соответствует 1, а False – значение 0. Для других логических типов значению True соответствует любое значение, не равное 0, а False – значение 0.

 

Стандартный символьный тип Char определяет полный набор символов стандарта ASCII. Каждому символу приписывается значение кода в диапазоне от 0 до 255. Функция Ord(X), где X имеет тип Char, дает код соответствующего символа.

 


Скалярные, пользовательские типы данных

 

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

Type <имя типа>=(< идентификатор 1 >, < идентификатор 2>, …,
< идентификатор n>);

Например, Type Week= (mon, twe, wen, tru, fri, sut, sun);

 

Интервальный тип в языке Паскаль определяется следующим образом. В любом порядковом типе можно выделить подмножество значений, определяемое минимальным и максимальным значением. Интервальный тип называется типом-диапазоном и определяется в разделе Type следующим образом:

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

Например,

Type A=1..100;

 

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

 

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

В языке Паскаль существуют следующие составные типы данных:

· тип-массив;

· строковый тип;

· тип-запись;

· тип-запись-с-вариантами;

· тип-множество;

· тип-файл.

 

Массивы

Данными типа «массив» являются массивы. Массив представляет собой фиксированное количество компонент одного и того же типа. Массив определяется… Массивы могут быть одномерными и многомерными. Для объявления типа-массива в…  

Строки

 

Данные строкового типа, или строки, представляют собой последовательности символов произвольной длины. Строку можно рассматривать как одномерный массив символов. В языке Borland Pascal 7.0 используются две разновидности строкового типа:

§ тип string;

§ тип Pchar.

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

Var

<имя переменной строкового типа>: string[<максимальная длина строки>];

Максимальная длина строки может быть не задана, тогда она равна 255 символам. Строка отличается от массива тем, что первый элемент строки имеет индекс 0 и служит для хранения текущей длины строки. Символы в строке нумеруются с единицы. Каждый символ занимает один байт. Таким образом, индекс элементов строки изменяется от нуля до максимальной длины строки.

Объявление строки вида

Var S1: string[10];

эквивалентно объявлению массива символов

Var S1: array [0..10] of char;

Если символьный массив объявлен как строка типа string, то нулевой символ будет заполняться автоматически Паскаль - системой. Если символьный массив объявлен как массив типа char, то нулевой символ не будет заполняться автоматически.

Символьная строка размещается в памяти ЭВМ следующим образом:

0 1 2 L N

L     ……        

где N – максимальная длина строки, L – текущая длина строки.

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

 

Program Stroki;

Var Str1, Str2, Str: string[80];

Begin

Str1:=’Turbo ’;

Str2:=’Pascal’;

Str:=Str1+Str2;

Writeln(‘Str=’,Str);

end.

 

 

В результате работы этой программы на экране будет отображено:

Str=Turbo Pascal

Следующие процедуры и функции модуля System используются для обработки символьных строк типа string:

ü Функция Concat(S1,S2,…,Sn) выполняет объединение нескольких строк S1,S2,…,Sn, где n>=2, возвращает объединенную строку. Если длина результирующей строки больше 255, она усекается до 255 символов.

ü Функция Copy(S1, Ind, Count) создает и возвращает подстроку строки S1, которая начинается с символа с номером Ind и имеет длину, равную Count.

ü Процедура Delete(S1, Ind, Count) удаляет подстроку из строки S1, которая начинается с символа с номером Ind и имеет длину, равную Count.

ü Функция Length(S1) определяет текущую длину строки S1.

ü Процедура Str(X,S) преобразует значение арифметического выражения X в строку S.

ü Процедура Insert(S1, S2, Ind) вставляет строку S2 в строку S1 после символа с номером Ind-1 строки S1.

ü Процедура Val(S, V, C) преобразует строку S в целое или вещественное число и присваивает его переменной V . Если строка S содержит символы, отличающиеся от цифр и других допустимых в числовых константах символов, то преобразования не выполняется а в переменную C помещается номер неправильного символа; С=0, если все символы правильные.

Записи

 

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

Переменная типа «запись» объявляется в разделе Var с помощью ключевого слова record следующим образом:

Var <имя переменной>: record

<поле 1>: <тип 1>;

<поле 2>: <тип 2>;

……

<поле n>: <тип n>;

end;

Ключевое слово «end» завершает объявление переменной типа «запись».

Количество полей записи может быть любым. Поля записи могут быть простыми переменными любого типа, массивами и другими записями. В разделе описания типов можно объявить имя типа «запись»:

Type <имя типа> = record

<поле 1>: <тип 1>;

<поле 2>: <тип 2>;

……

<поле n>: <тип n>;

end;

Тогда объявление переменной типа «запись» будет иметь следующий вид:

Var <имя переменной>: <имя типа «запись»>;

Например,

Type Tstudent = record

FAM: string[20]; {фамилия}

IM: string[20]; {имя}

OT: string[30]; {отчество}

GR: integer; {год рождения}

NZACH: integer; {номер зачетки}

NGR: string[30]; {номер группы}

end;

Var Zap_St: Tstudent;

Доступ к элементам (полям) записи производится с помощью составного имени:

<имя переменной типа «запись»>.<имя поля>.

Например,

Zap_St.FAM:=’Иванов’; или

Readln(Zap_St.FAM);

Для того, чтобы не писать имя переменной типа «запись» при каждом обращении к ее полям, можно использовать оператор with, называемый оператором присоединения, который имеет следующий синтаксис:

with <список ссылок на переменную> do <оператор>; или

with <список ссылок на переменную> do begin

<операторы>

end;

Например,

Type T_Rec = record

A:integer ;

B: byte;

C: char;

end;

Var Rec: T_Rec;

……….

begin

……….

with Rec do begin

A:=10;

B:=1;

C:=’*’;

End;

Данный оператор with эквивалентен следующей последовательности операторов:

Rec.A:=10; Rec.B:=1; Rec.C:=’*’;

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

Константы типа «запись» определяются в разделе Const следующим образом:

Const <имя константы>: <имя типа «запись»>=

(<имя поля 1>:<значение поля 1>;

<имя поля 2>:<значение поля 2>;

…………………………………..

<имя поля n>:<значение поля n >) ;

Например,

Type Data= record

Y: integer;

M: 1..12;

D: 1..31;

End;

Const DR: Data=(Y:1984;

M: 4;

D: 12);

Записи с вариантами

 

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

· фиксированную часть;

· вариантную часть.

Вариантные компоненты включаются в зависимости от признака. Тип записи с вариантами объявляется следующим образом:

Type <имя типа> = record

Case <признак варианта>: <тип признака> of

<константа 1>: (<описание поля 11>;

< описание поля 12>;

< описание поля 1n1>);

<константа 2>: (<описание поля 21>;

< описание поля 22>;

< описание поля 2n2>);

……

<константа k>: (<описание поля k1>;

< описание поля k2>;

< описание поля knk>);

End;

Например,

Type Coordinates = record

case kind: (dekart,polar) of

dekart: (x, y: real);

polar: (r, fi: real)

End;

В данном примере определено объединение двух взаимно исключающих вариантов. Однако на практике приходится объединять два типа с частично совпадающими компонентами. Для такой ситуации применяется тип «запись с вариантами», который объявляется следующим образом типа:

Type <имя типа> = record

<поле 1>: <тип 1>;

<поле 2>: <тип 2>;

……

<поле n>: <тип n>;

Case <признак варианта>: <тип признака> of

<константа 1>: (<описание поля 11>;

< описание поля 12>;

< описание поля 1n1>);

<константа 2>: (<описание поля 21>;

< описание поля 22>;

< описание поля 2n2>);

……

<константа k>: (<описание поля k1>;

< описание поля k2>;

< описание поля knk>);

End;

 

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

Type Zap_OK = record

Fio: string[80]; {Фамилия, имя, отчество }

TabN: integer; {}

Otdel: integer; {}

Gpr: integer; {}

Case prizn: byte of

1: (spec_dipl: string[80]; {специальность по диплому}

nom_dipl: string[10]; {номер диплома}

stag: integer); {стаж работы по специальности}

2: (Nmvuz:string[80]; {наименование вуза, где учится сотрудник}

Nk: byte; { номер курса}

P_I_O: byte) {признак использования учебного отпуска}

End;

 

Множества

Тип-множество, используемый в языке Паскаль, соответствует понятию множества в математике, и создается с помощью следующего конструктора типа: Type T = set of T0; где T0 – базовый тип или тип элементов множества.

Файлы

 

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

Файлом называется конечное множество компонент одного и того же типа, расположенных во внешней памяти. Компоненты файла могут быть любого типа. Число компонент не объявляется заранее и может изменяться. Новая компонента добавляется только в конец файла. У понятия файл есть две стороны. С одной стороны , файл – это именованная область внешней памяти, содержащая некоторую информацию. Файл в таком понимании называется физическим файлом. Физический файл имеет имя файла во внешней памяти, которое регистрируется в некотором каталоге (папке) на диске средствами операционной системы.

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

TYPE <имя типа «файл»>= file of <тип компонент файла>;

Например,

TYPE NumberFL = file of integer;

Объявив тип «файл», можно описывать файловые переменные заданного типа в разделе VAR:

VAR F1: NumberFL;

Тип «файл» можно определять непосредственно при описании файловой переменной, тогда ее объявление имеет следующий вид:

VAR F1: file of integer;

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

С файлами выполняются следующие операции:

· связывание файловой переменной с конкретным физическим файлом на внешнем устройстве;

· открытие файла для работы в заданном режиме: для чтения, для записи или для добавления;

· чтение информации из файла;

· запись информации в файл;

· закрытие файла.

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

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

VAR F1: file of <тип компонент>;

F2: text;

F3: file;

где F1 – типизированный файл; каждая его компонента имеет заданный тип;

F2 – текстовый файл; его компоненты – строки символов;

F3 – нетипизированный файл; тип его компонент не указан, что делает его совместимым с любыми файлами.

 

Доступ к компонентам файлов.

Любой программе на Паскале[5] доступны без каких-либо предварительных объявлений два файла со стандартными файловыми переменными:

Input – для чтения данных со стандартного устройства ввода (клавиатуры);

Output – для вывода на стандартное устройство вывода (видеомонитор).

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

Процесс обработки файла можно представить в виде блок-схемы, показанной на рис. 5.1.

 

 
 

 



Связывание файловой переменной с физическим файлом выполняет процедура Assign, обращение к которой имеет вид:

Assign(<имя файловой переменной>,<имя файла на внешнем устройстве>);

где <имя файловой переменной> - это переменная типа «файл», объявленная в программе;

<имя файла на внешнем устройстве> - это строка символов, содержащая полное имя файла на диске и, возможно, путь к этому файлу.

Например,

Assign(F1,’c:\prog1.txt’);

Assign(F2,’a:\c1\data1.txt’);

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

VAR Name: string;

F2: file of integer;

………………………..

write(‘Введите имя файла: ’);

readln(Name);

assign (F2,Name);

…………………………

В этом фрагменте программы в качестве второго аргумента процедуры assign используется переменная Name, значение которой - строка, содержащая имя физического файла.

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

reset(<имя файловой переменной>).

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

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

rewrite (<имя файловой переменной>).

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

Процедура открытия существующего файла в режиме добавления
append применима только к файлам типа text. Обращение к процедуре append имеет следующий вид:

append(<имя файловой переменной типа text>).
Если открываемый файл отсутствует, то при выполнении процедуры append возникает ошибка ввода-вывода. При открытии файла в режиме добавления новые данные записываются в конец файла.

Завершение действий с любым файлом выполняется процедурой
close (<имя файловой переменной>).
Работа с файлами осуществляется с использованием буферов в оперативной памяти. Одним из действий процедуры close является очистка буферов ввода-вывода. Без выполнения этой процедуры часть информации, предназначенная для записи в файл, может быть потеряна.

При работе с файлами автоматически проверяются ошибки ввода-вывода. Если проверка включена по умолчанию или с помощью директивы компилятора{$I+}, то при возникновении ошибки выполнение программы автоматически завершается. Если проверка выключена с помощью директивы{$I-}, то программа продолжает работу и проверить результат можно с помощью стандартной функции IOResult. Функция IOResult возвращает код завершения последней операции ввода-вывода. Если IOResult равно нулю, то завершение операции – успешно. Например, в записанном ниже фрагменте программы проверяется корректность открытия существующего файла:

VAR

F1: text;

Fn: string;

……………..

begin

……………….

write(‘Введите имя файла: ’);

readln(Fn);

assign (F2,Fn);

{$I-}

reset(F1);

{$I+}

If IOResult<>0 then begin

Writeln(‘файл не найден!’); Halt;

end;

……………………………..

Процедура Halt производит немедленное завершение выполнения программы.

 

Процедуры ввода-вывода для текстовых файлов.

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

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

q Eoln(<имя файловой переменной типа text >) – возвращает значение true, если достигнут конец строки;

q Eof(<имя файловой переменной типа text >) – возвращает значение true, если достигнут конец файла.

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

q Read(<имя файловой переменной >,< список ввода >) ;

q Readln (<имя файловой переменной >,< список ввода >).

Процедура Readln в отличие от процедуры Read после ввода всех переменных в списке игнорирует непрочитанные данные до конца текущей строки, и последующее чтение осуществляется с новой строки. Процедура Readln<имя файловой переменной >
(без списка ввода) производит переход к следующей строке файла.

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

q write(<имя файловой переменной >,< список вывода >) ;

q writeln(<имя файловой переменной >,< список вывода >).

Процедура writeln в отличие от процедура write выполняет запись символа «конец строки» и может вызывать без списка вывода:
writeln<имя файловой переменной >. Пример программы ввода элементов матрицы из текстового файла приведен в разделе 8.6 данного учебного пособия.

 

Процедуры ввода-вывода для типизированных файлов

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

Read(<имя файловой переменной >,< список ввода >).

В списке ввода содержатся переменные того же типа, что и тип файла. При считывании в каждую переменную данных из файла указатель текущей позиции перемещается на следующую компоненту файла. Если указатель текущей позиции файла находится за последним компонентом файла, то достигнут конец файла, и стандартная функция
Eof(<имя файловой переменной >) возвратит значение True.

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

write(<имя файловой переменной >,< список вывода >) ;

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

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

FilePos – функция, возвращающая номер текущей позиции указателя в файле;

FileSize – функция, возвращающая текущий размер файла;

Seek – процедура, перемещающая указатель файла на заданную позицию;

Truncate – процедура, которая усекает размер файла до текущей позиции.

 

Процедуры ввода-вывода для нетипизированных файлов.

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

Чтение компонент из файла производится процедурой:
BlockRead(F,Buf,N,Result),

где F – имя файловой переменной;

Buf – переменная любого типа, являющаяся буфером для размещения вводимой информации;

N – число компонент, которое нужно прочитать;

Result – переменная, в которую помещается фактическое число прочитанных компонент.

Запись компонент в файл производится процедурой:
BlockWrite(F,Buf,N,Result),

где F – имя файловой переменной;

Buf – переменная любого типа, являющаяся буфером для размещения выводимой информации;

N – число компонент, которое нужно записать;

Result – переменная, в которую помещается фактическое число записанных компонент.

 

Операции над данными скалярных типов. Выражения

 

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

Операнды – это данные, которые участвуют в вычислении; в качестве операндов могут быть константы, переменные и функции со списками параметров в круглых скобках.

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

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

§ приоритетом операций;

§ порядком расположения операции;

§ использованием скобок.

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

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

1) арифметические операции:

a. унарные: +,-;

b. бинарные: +,-,*,/,div,mod;

2) операции отношения:

= , <>, <=,>=,>,<;

3) логические операции:

not, and, or, xor;

4) поразрядные операции:

not, and, or, xor, shl, shr.

 

Унарные, арифметические операции представлены в табл. 6.1.

 

Табл. 6.1. Унарные операции

Операция Действие Тип операндов Тип результата
+ Сохранение знака Целый вещественный Целый вещественный
- Изменение знака Целый вещественный Целый вещественный

 

Бинарные, арифметические операции представлены в табл. 6.2.

 

Табл. 6.2. Бинарные операции

Операция Действие Тип операндов Тип результата
+ Сложение Целый вещественный Целый вещественный
- Вычитание Целый вещественный Целый вещественный
* Умножение Целый вещественный Целый вещественный
/ Деление вещественный Вещественный
Div Деление нацело Целый Целый
Mod Остаток от деления Целый Целый

 

Операции отношения представлены в таблице 6.3.

Табл. 6.3 . Операции отношения

Операция Сравнение на Тип операндов Тип результата
= Равно Совместимый скалярный тип Булевский
<> Не равно Совместимый скалярный тип Булевский
< Меньше Совместимый скалярный тип Булевский
> Больше Совместимый скалярный тип Булевский
<= Меньше или равно Совместимый скалярный тип Булевский
>= Больше или равно Совместимый скалярный тип Булевский

 

Логические операции выполняются по правилам булевой алгебры, представленным в таблице 6.4.

Табл. 6.4. Таблица истинности логических операций

Операнды Операции
A B Not A A and B A or B A xor B
False False True False False False
False True True False True True
True False False False True True
True True False True True False

Логические операции and (конъюнкция), or (дизъюнкция), xor (исключающее ИЛИ) являются бинарными; операнды A и B булевского типа, и результат – булевского типа. Логическая операция not является унарной; ее операнд и результат имеют булевский тип.

 

Стандартные, математические функции приведены в табл. 6.5. Математические функции можно использовать только с аргументами целого и вещественного типа.

 

Табл. 6.5. Арифметические функции

функция назначение Тип результата
Abs(X) Абсолютная величина числа Совпадает с типом аргумента
Arctan(X) Арктангенс Вещественный
Cos(X) Косинус Вещественный
Exp(X) ex Вещественный
Frac(X) Дробная часть числа Вещественный
Int(X) Целая часть числа Вещественный
Ln(X) Натуральный логарифм Вещественный
Pi Значение π Вещественный
Sin(X) Синус Вещественный
Sqr(X) Квадрат числа Х Совпадает с типом аргумента
Sqrt(X) Вещественный

 

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

tg(X)=sin(X)/cos(X);

ctg(X)=1/tg(X);

loga(X)=ln(X)/ln(A)

Ax=exp(X*ln(A)), X-вещественное число, A>0;

arcsin(X)=arctan(X/sqrt(1-sqr(X)));

arccos(X)=arctan(sqrt(1-sqr(X))/X).

 

Поразрядные (битовые) операции выполняются над кодами целых чисел; к ним относятся битовые логические операции и операции сдвига, приведенные в табл.6.6.

 


Табл. 6.6. Поразрядные операции

Операция Действие Тип операндов Тип результата
Not Битовое отрицание Целый Целый
And Битовая конъюнкция Целый Целый
Or Битовая дизъюнкция Целый Целый
Xor Битовое исключающее ИЛИ Целый Целый
Shl Битовый сдвиг влево Целый Целый
Shr Битовый сдвиг вправо Целый Целый

 

Пример.

 

Операнд/ Результат Десятичное значение Двоичное значение
A
B
Not A
A and B
A or B
A xor B
A shr B
A shl B

 

Приоритеты операции над данными скалярных типов приведены в табл. 6.7.

Табл. 6.7. Приоритеты операций

приоритет Тип операций Знаки операции
Вычисления в круглых скобках ( )
Вычисление значения функции <имя_функции>(<список_аргументов>)
Унарные операции Not, +,-
Операции типа умножения *, /, div,mod,and,shl,shr
Операции типа сложения +, -, or, xor
Операции отношения =,<>, >=, <=,>, <

 

Одноприоритетные операции выполняются в порядке следования слева направо.


Операторы языка Паскаль

 

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

§ простые операторы;

§ структурные операторы.

К простым операторам относятся оператор присваивания, оператор вызова процедуры и оператор перехода.

К структурным операторам относятся составной оператор, условные операторы, операторы цикла.

 

Простые операторы

 

Оператор присваивания имеет следующий синтаксис:

 

<имя переменной>:=<выражение>

:= ¾ знак операции присваивания.

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

§ они описаны одним и тем же описателем;

§ в случае целых типов допустимы следующие присваивания:

· переменной типа longint можно присваивать значения типа byte, integer, word;

· переменной типа Integer можно присваивать значения типа byte;

· переменной типа Word можно присваивать значения типа byte;

§ вещественной переменной типа real, single, double можно присвоить значение целого типа;

§ переменной порядкового типа можно присваивать значения типа-диапазона этого типа.

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

Примеры оператора вызова процедуры.

 

Read(A,B,C); { ввод с клавиатуры значений переменных A, B, C }

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

 

Оператор перехода состоит из ключевого слова goto и следующей за ним метки:

Goto <метка>.

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

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

Для ввода числовых и символьных данных используются стандартные процедуры read и readln. Числовые значения при вводе разделяются пробелами или вводятся с новой строки. Значения, разделенные пробелами, сначала заносятся в буфер и после нажатия клавиши ENTER пересылаются в оперативную память ПК. Максимальная длина буфера ввода-вывода равна 127 байтам.

Пример 1.

Var

R: real;

I: integer;

………………………..

read(R,I);

………………………..

Вводимые данные:

33.45 18 Enter

 

В результате R будет равно 33.45, а I – 18.

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

 

Пример 2.

Var

R: real;

I: integer;

………………………..

read(R,I);

………………………..

Вводимые данные:

33.45 Enter

18 Enter

 

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

Пример 3.

Var

R: real;

I: integer;

………………………..

R:=5.9; I:=7;

………………………..

write(‘R= ‘,R, ‘I=’,I);

………………………..

Выводимые данные:

К=5.9 Ш=7 Enter

 

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

 

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

 

Составной оператор объединяет группу операторов в единое целое, после чего они рассматриваются компилятором как один оператор.

Составной оператор имеет следующий синтаксис:

Begin <оператор 1>; <оператор 2>; …<оператор n> end

Составной оператор используется в тех случаях, когда в программе допускается написать один оператор, а требуется выполнить группу операторов. Составной оператор соответствует алгоритмической структуре “Следование” (см. рис. 7.1).

К условным операторам относятся операторы if и case. Условный оператор if обеспечивает выбор из двух альтернатив в зависимости от условия и имеет следующий синтаксис:

If <логическое выражение> then <оператор 1> else <оператор 2>;

Оператор 1 выполняется, если значение логического выражения – True, а оператор 2 выполняется, если значение логического выражения – False.

Оператор If допускается в неполной форме:

If <логическое выражение> then <оператор >;

Если после then и else необходимо выполнить группу операторов, то они должны быть объединены в составной оператор, например,

If A>B then begin X:=A+B; Y:=A*B end;

Условный оператор соответствует алгоритмической структуре “Разветвление”, блок-схема которой на рис. 7.2.


 

 


……………..

       
   
 
 

 

 

 
 

 


 

 
 
Рис. 7.2

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

Case <выражение> of

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

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

……

<список констант n>: <оператор n>

else <оператор >

end;

 

Перед else точка с запятой не ставится. Ветвь else может отсутствовать.

Список констант может содержать одну константу; несколько констант, разделенных запятыми; или интервал значений
<значение 1>.. <значение 2>.

 

Пример.

 

Var Symbol: Char;

…………………….

Begin

…………………….

Case Symbol of

‘0’..’9’: writeln(‘Это цифра’);

‘A’..’Z’: writeln(‘Это прописная буква’);

‘a’..’z’: writeln(‘Это строчная буква’);

‘=’: writeln(‘Это знак операции сравнения’)

else writeln(‘другой символ’);

end;

 

Рассмотрим операторы цикла языка Паскаль. Язык Паскаль поддерживает три конструкции цикла:

· оператор цикла с предусловием while-do;

· оператор цикла с постусловием repeat-until;

· оператор цикла с параметром for.

Оператор while-do имеет следующий синтаксис:

While < логическое выражение >

do <оператор>

или

While < логическое выражение >

begin

<операторы>

end

Блок-схема оператора цикла представлена на рис. 7.3. Тело цикла – это оператор или составной оператор. В операторе while-do тело цикла может не выполниться ни разу. Логическое выражение – это условие продолжения цикла. Проверка условия продолжения цикла выполняется перед очередной итерацией. Итерация – это выполнение операторов тела цикла.

 

       
 
 
   
Рис. 7.3

 

 


Оператор цикла repeat-until имеет следующий синтаксис:

Repeat

<оператор 1>

<оператор 2>

….

<оператор n>

until <логическое выражение>

В операторе repeat-until не требуется использование составного оператора. Блок-схема оператора repeat-until показана на рис. 7.4, где логическое выражение является условием выхода из цикла. Операторы тела цикла repeat-until выполняются хотя бы один раз. Проверка условия выхода из цикла происходит после очередной итерации.

Оператор цикла с параметром используется в тех случаях, когда точно известно число итераций, отсчет числа итераций выполняется с помощью управляющей переменной, которая называется параметром цикла. Перед выполнением цикла известны начальное N1 и конечное N2 значение параметра цикла. Шаг изменения параметра равен 1.

Если N1<N2 (см. рис. 7.5) , то оператор цикла с параметром имеет следующий синтаксис:

For <параметр цикла>:=<выражение N1> to <выражение N2>
do <оператор или составной оператор>

Если N1>N2 (см. рис. 7.6) , то оператор цикла с параметром имеет следующий синтаксис:

For <параметр цикла>:=<выражение N1> downto <выражение N2>
do <оператор или составной оператор>

В Паскале оператор цикла с параметром имеет два ограничения:

· Шаг изменения параметра может быть равен только 1, если используется ключевое слово to, или –1,если используется ключевое слово downto.

· Переменная – параметр цикла должна быть только порядкового типа и должна быть локальной.

 

 
 

       
 
 
   
Рис. 7.5


       
 
 
   
Рис. 7.6

8. Примеры программ на языке Паскаль

 


Пример 1. Арифметические выражения. Оператор присваивания

 

Задание 1. Вычислить значение функции

. Значение аргумента Х вводится с клавиатуры.

Постановка задачи.

Входные данные:

Х – аргумент функции Y.

Выходные данные:

Y – значение функции.

Метод решения: вычисление значения функции по заданной формуле.

 

Алгоритм. Вычисление значения функции.

Входные данные.

СКАЛЯР Х – вещественное число.

Выходные данные.

СКАЛЯР Y – вещественное число.

Начало

ввод(Х)

вывод(Y)

Конец


Блок-схема алгоритма.

 

Определение Y по заданной формуле
Ввод числа Х

 

 

Вывод значения Y

 

 
 
Рис 8.1


Программа на языке Паскаль.

Program Example1;

Var X,Y: real;

Begin

Write(‘Input X: ‘);

Readln(X);

Y:=(X*sqr(X) +6)/sqrt(sqr(X)+6)+4;

Write(‘Y= ‘,Y);

End.

 

Результаты тестирования.

Если X=1.2, Y должен быть равен 6.83322226.

Результаты, выданные программой.

 

Input X: 1.2

Y= 6.83322226221255E+0000

 

Пример 2. Условные операторы

 

Задание 1. Вычислить значение функции в зависимости от условия.

.

Значения аргумента Х и параметра A вводятся с клавиатуры.

Постановка задачи.

Входные данные:

А – постоянный параметр функции Y, A>0,

Х – аргумент функции Y.

Выходные данные:

Y – значение функции.

Метод решения: проверка условия и вычисление значения функции по заданной формуле.

 

Алгоритм. Вычисление значения функции в зависимости от условия.

Входные данные.

СКАЛЯР Х – вещественное число,

А – положительное, вещественное число.

Выходные данные.

СКАЛЯР Y – вещественное число.

Начало

ввод(Х,А)

ЕСЛИ X<0 ТО

Y=(X-A)/X

ИНАЧЕ

ЕСЛИ X<A ТО Y=0

ИНАЧЕ Y= A-ln|X-1|

КОНЕЦ_ЕСЛИ

КОНЕЦ_ЕСЛИ

вывод(Y)

Конец

 


Блок-схема алгоритма.

Ввод чисел Х, А

 

 

 
 

 


 

 

 
 

 


Рис. 8.2
Вывод значения Y


Программа на языке Паскаль.

Program Example1;

Var A,X,Y: real;

Begin

While(A<=0) do

begin

Write(‘Input A>0: ‘);

Readln(A)

End;

Write(‘Input X: ‘);

Readln(X);

If X<0 Then

Y:=(X-A)/X

Else

If X<A Then Y:=0

Else Y:=A-ln(abs(X-1));

Write(‘Y= ‘,Y);

End.

 

Результаты тестирования.

A=1

Если X=-1.5, Y должен быть равен 1.66667.

Если X=0.5, Y должен быть равен 0.

Если X=1.5, Y должен быть равен 1,69314718.

Результаты, выданные программой.

 

Input A>0: 1

Input X: -1.5

Y= 1.66666666666667E+0000

 

Input A>0: 1

Input X: 0.5

Y= 0.00000000000000E+0000

 

Input A>0: 1

Input X: 1.5

Y= 1.69314718055995E+0000

 


Пример 3. Программа обработки одномерного массива

 

Задание 3. Определить минимальный элемент среди положительных элементов одномерного массива. Если положительных элементов нет в массиве, вывести сообщение об этом.

 

Постановка задачи.

Исходные данные:

· Число элементов в одномерном массиве n<=10;

· Одномерный массив из n элементов, содержащий положительные и отрицательные значения.

Выходные данные: значение минимального элемента среди положительных элементов массива.

Аномалии: отсутствие положительных элементов в массиве.

Реакция на аномальную ситуацию – выдача сообщения.

 

Алгоритм. Поиск минимального элемента среди положительных элементов массива.

Исходные данные:

СКАЛЯР n<=10 - целое число;

МАССИВ M[10] целого типа.

Выходные данные:

СКАЛЯР min – целое число.

Промежуточные данные:

СКАЛЯР i – целое число /* параметр цикла */

i1 – целое число /* номер первого положительного элемента в массиве */

Начало

Вывод(‘input n<10’)

Ввод(n)

ЦИКЛОТ i:=1 ДО n

Вывод(‘input M[i] ‘)

Ввод(M[i])

КОНЕЦ_ЦИКЛА

i1:=0

ЦИКЛ

i1:= i1+1

ДО ((M[i1]>0) ИЛИ (i1>n))

ЕСЛИ i1>n ТО

Вывод(‘not M[i]>0 ‘)

ИНАЧЕ

min:=M[i1]

ЦИКЛОТ i:=i1 ДО n

ЕСЛИ ((min> M[i]) И (M[i]>0)) ТО

Min:=M[i]

КОНЕЦ_ЕСЛИ

КОНЕЦ_ЦИКЛА

Вывод(‘min= ‘,min)

КОНЕЦ_ЕСЛИ

Конец

 


Блок-схема алгоритма.

 

 

 

 
 

 

 


 
 

 

 




Программа на языке Паскаль.


Program Min_Positive;

Var

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

i,n,i1, min: integer;

begin
write(‘input n<10’);

readln(n);
for i:=1 to n do read(M[i]);

i1:=0;

repeat i1:=i1+1 until(M[i1]>0) or (i1>n);

if i1>n then writeln(‘not M[i]>0’)

else begin

min:=M[i1];

for i:=i1 to n do

if (M[i]>0) and (min >M[i]) then min:=M[i];
writeln(‘min= ‘,min);

end

end.

 

Результаты тестирования.

1. Исходные данные:

n=5

M=(-1,-2,-3,-4,-5)

Результат- сообщение «not M[i]>0».

Результаты, выданные программой.

input n<10 5

-1 -2 -3 -4 -5

not M[i]>0

2. Исходные данные:

n=5

M=(9,-2,3,4,-5)

Результат- сообщение «min=3».

Результаты, выданные программой.

input n<10 5

9 -2 3 4 -5

min= 3


Пример 4. Программа обработки двумерного массива

 

Задание 4. В двумерном массиве (матрице) определить номер строки, в которой находится максимальное количество положительных элементов. Если положительных элементов нет в массиве, вывести сообщение об этом.

 

Постановка задачи.

Исходные данные:

· Число строк в матрице n<=10;

· Число столбцов в матрице m<=10;

· Двумерный массив (матрица) размером n x m , содержащий положительные и отрицательные значения.

Выходные данные: номер строки, в которой находится максимальное количество положительных элементов.

Аномалии: отсутствие положительных элементов в массиве.

Реакция на аномальную ситуацию – выдача сообщения.

 

Алгоритм. Подсчет числа положительных элементов в строках матрицы.

Исходные данные:

СКАЛЯР n<=10 - целое число;

СКАЛЯР m<=10 - целое число;

МАССИВ A[n x m] целого типа.

Выходные данные:

СКАЛЯР imax – целое число.

Промежуточные данные:

МАССИВ K[n] целого типа /* массив счетчиков количества положительных элементов в строках матрицы */

СКАЛЯР kmax – целое число /* максимальное количество положительных элементов */

СКАЛЯР i – целое число /* параметр цикла */

СКАЛЯР j – целое число /* параметр цикла */

Начало

Вывод(‘input n<10’)

Ввод(n)

Вывод(‘input m<10’)

Ввод(m)

ЦИКЛОТ i:=1 ДО n

ЦИКЛОТ j:=1 ДО m

Вывод(‘input A[i,j] ‘)

Ввод(A[i,j])

КОНЕЦ_ЦИКЛА

КОНЕЦ_ЦИКЛА

ЦИКЛ ОТ i:=1 ДО n

K[i]=0;

ЦИКЛ ОТ j:=1 ДО m

ЕСЛИ(A[i,j]>0) ТО

K[i]= K[i]+1

КОНЕЦ_ЕСЛИ

КОНЕЦ_ЦИКЛА

КОНЕЦ_ЦИКЛА

Kmax=K[1]

imax=1

ЦИКЛ ОТ i:=1 ДО n

ЕСЛИ (K[i]>Kmax) ТО

Kmax=K[i]

imax=i

КОНЕЦ_ЕСЛИ

КОНЕЦ_ЦИКЛА

ЕСЛИ (Kmax=0) ТО

Вывод(‘Not A[i,j]>0!’)

ИНАЧЕ

Вывод(‘imax= ‘,imax)

КОНЕЦ_ЕСЛИ

Конец

 


Блок-схема алгоритма.

 

 

 

 
 

 

 


Подсчет количества положительных элементов в каждой строке матрицы и запись счетчиков в массив K

 

 

 
 

 

 


Рис. 8.4


Блок-схема алгоритма ввода матрицы M размером n x m.

 

I=1

 
 

 


 

           
 
   
 
 
   
Рис. 8.5

 

 



Блок-схема алгоритма подсчета количества положительных элементов в каждой строке матрицы и запись счетчиков в массив K из n элементов.

K[I]= количество A[I, J], таких что A[I, J]>0.

 



Блок-схема алгоритма определения номера строки матрицы, содержащей максимальное количество положительных элементов .

 

 

 



Программа на языке Паскаль.


Program Nomer_Row;

Var

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

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

i, j, n, m, kmax, imax: integer;

begin

write('input n<10 ');

readln(n);

write('input m<10 ');

readln(m);

for i:=1 to n do

for j:=1 to n do

read(A[i,j]);

for i:=1 to n do

begin

K[i]:=0;

for j:=1 to m do

if (A[i,j]>0) then

K[i]:= K[i]+1;

end;

kmax:=K[1];

imax:=1;

for i:=1 to n do

if (K[i]>kmax) then

begin

kmax:=K[i];

imax:=i;

end;

if kmax=0 then

writeln('Not A[i][j]>0 !')

else

writeln('imax= ',imax);

write('PRESS ANY KEY!');

readln;

end.

 

Результаты тестирования.

1. Исходные данные:

n=3

m=3

A=((-1,-2,-3), (-1,0,-3), (-5,-2,-8)

Результат- сообщение «not A[i,j]>0».

Результаты, выданные программой.

 

input n<10 3

input m<10 3

-1 -2 -3

-1 0 -3

-5 -2 -8

Not A[i][j]>0 !

PRESS ANY KEY!

 

2. Исходные данные:

n=3

m=3

A=((1,2,3), (1,0,-3), (-5,-2,-8)

Результат- сообщение «imax=1».

Результаты, выданные программой.

input n<10 3

input m<10 3

1 2 3

1 0 -3

-5 -2 -8

imax= 1

PRESS ANY KEY!

 

Пример 5. Программа обработки символьных строк

 

Задание 5. В массиве строк (тексте) определить число слов.

Постановка задачи.

Исходные данные:

· Число строк в тексте ns<=10;

· Массив размером ns , содержащий символьные строки максимальной длины, равной 255.

Выходные данные: количество слов в тексте.

 

Алгоритм. Подсчет числа слов в тексте.

Исходные данные:

СКАЛЯР ns<=10 - целое число;

МАССИВ Mtext[ns] типа string.

Выходные данные:

СКАЛЯР K – целое число.

Промежуточные данные:

СКАЛЯР i – целое число /* параметр цикла */

СКАЛЯР j – целое число /* параметр цикла */

Начало

Вывод(‘input ns<10’)

Ввод(ns)

ЦИКЛОТ i:=1 ДО ns

Вывод(‘line ‘,i)

Ввод(Mtext[i])

КОНЕЦ_ЦИКЛА

K=0;

ЦИКЛ ОТ i:=1 ДО ns

ЦИКЛ ОТ j:=1 ДО length(Mtext[I])

ЕСЛИ (Mtext[i,j]=’ ‘) ТО

K= K+1

КОНЕЦ_ЕСЛИ

КОНЕЦ_ЦИКЛА

КОНЕЦ_ЦИКЛА

вывод(‘K= ‘, K)

Конец

 


Блок-схема алгоритма.

 

 

 

 

 


K=0

 

 


True

       
 
 
   
Рис. 8.8


 


Program K_Words;

Var

Mtext: array[1..10] of string;

i, j, ns, k: integer;

begin

writeln;

write('input ns<10 ');

readln(ns);

for i:=1 to ns do

begin

write(' Line ',i,': ');

readln(Mtext[i]);

end;

k:=0;

for i:=1 to ns do

begin

for j:=1 to length(Mtext[i]) do

if (Mtext[i,j]=' ') then

k:= k+1;

k:= k+1;

end;

writeln(k,' words in the text ');

write('PRESS ANY KEY!');

readln;

end.

 

Результаты тестирования.

1. Исходные данные:

ns=3

Mtext= (‘В этой программе определяется’,

‘число слов в тексте.’

‘Слова разделяются пробелами.’)

Результат – сообщение «11 words in the text».

Результаты, выданные программой.

 

input ns<10 3

Line 1: В этой программе определяется

Line 2: число слов в тексте.

Line 3: Слова разделяются пробелами.

11 words in the text

PRESS ANY KEY!


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

 

Задание 6. В двумерном массиве (матрице) определить номер строки, в которой находится максимальное количество положительных элементов. Если положительных элементов нет в массиве, вывести сообщение об этом.

Исходные данные ввести из текстового файла, сохраняемого на диске.

 

Постановка задачи.

Исходные данные.

q Имя текстового файла на диске

q Текстовый файл на диске с указанным именем, содержащий следующую информацию:

o число строк в матрице n<=10;

o число столбцов в матрице m<=10;

o двумерный массив (матрица) размером n x m , содержащий положительные и отрицательные значения.

Выходные данные: номер строки, в которой находится максимальное количество положительных элементов.

Аномалии:

· отсутствие файла с исходными данными на диске;

· отсутствие положительных элементов в массиве.

Реакция на аномальную ситуацию – выдача сообщения.

 

Алгоритм. Подсчет числа положительных элементов в строках матрицы.

Исходные данные:

СТРОКА fn – имя входного файла на диске;

ФАЙЛ F1 – входной, текстовый файл (файловая переменная);

СКАЛЯР n<=10 - целое число;

СКАЛЯР m<=10 - целое число;

МАССИВ A[n x m] целого типа.

Выходные данные:

СКАЛЯР imax – целое число.

Промежуточные данные:

МАССИВ K[n] целого типа /* массив счетчиков количества положительных элементов в строках матрицы */

СКАЛЯР kmax – целое число /* максимальное количество положительных элементов */

СКАЛЯР i – целое число /* параметр цикла */

СКАЛЯР j – целое число /* параметр цикла */

Начало

Вывод(‘input filename’)

Ввод(fn)

Связывание файловой переменной F1 c файлом, имя которого fn

Отключение проверки завершения операции ввода-вывода

Открытие файла F1 в режиме чтения

Включение проверки завершения операции ввода-вывода

Если IOResult<>0 то

Вывод(‘File not found!’)

Принудительное завершение программы

КОНЕЦ_ЕСЛИ

Ввод_из_файла(n)

Ввод_из_файла (m)

ЦИКЛОТ i:=1 ДО n

ЦИКЛОТ j:=1 ДО m

Ввод_из_файла (A[i,j])

КОНЕЦ_ЦИКЛА

КОНЕЦ_ЦИКЛА

ЦИКЛ ОТ i:=1 ДО n

K[i]=0;

ЦИКЛ ОТ j:=1 ДО m

ЕСЛИ (A[i,j]>0) ТО

K[i]= K[i]+1

КОНЕЦ_ЕСЛИ

КОНЕЦ_ЦИКЛА

КОНЕЦ_ЦИКЛА

Kmax=K[1]

imax=1

ЦИКЛ ОТ i:=1 ДО n

ЕСЛИ (K[i]>Kmax) ТО

Kmax=K[i]

imax=i

КОНЕЦ_ЕСЛИ

КОНЕЦ_ЦИКЛА

ЕСЛИ (Kmax=0) ТО

Вывод(‘Not A[i,j]>0!’)

ИНАЧЕ

Вывод(‘imax= ‘,imax)

КОНЕЦ_ЕСЛИ

Закрытие файла

Конец

Блок-схема данного алгоритма, описанного на псевдокоде, представлена на рис. 8.9.

 


Блок-схема алгоритма.

       
 
 
   
Рис. 8.9



Программа на языке Паскаль.

 


Program Nomer_Row;

Var

F1: text;

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

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

i, j, n, m, kmax, imax: integer;

fn: string;

begin

write('input filename '); readln(fn);

assign(F1,fn);

{$I-} Reset(F1); {$I+}

if IOResult<>0 then

begin

write('File ', fn, ' not found!'); readln; Halt;

End;

read(F1,n); read(F1,m);

for i:=1 to n do begin

for j:=1 to n do begin

read(F1,A[i,j]);

write(A[i,j],' ');

end;

writeln;

end;

for i:=1 to n do begin

K[i]:=0;

for j:=1 to m do

if (A[i,j]>0) then

K[i]:= K[i]+1;

end;

kmax:=K[1]; imax:=1;

for i:=1 to n do

if (K[i]>kmax) then begin

kmax:=K[i]; imax:=i;

end;

if kmax=0 then writeln('Not A[i][j]>0 !')

else writeln('imax= ',imax);

close(F1);

write('PRESS ANY KEY!');

readln;

end.

 


Результаты тестирования.

1. Исходные данные:

Текстовый файл matrix.txt, содержащий следующую информацию

<n - число строк > <m - число столбцов>

<матрица n x m, элементы разделяются пробелами, каждая строка матрицы записывается в отдельной строке файла>

a) Тестовый пример 1:

Файл matrix.txt

4 4

1 2 -3 -6

-3 -9 0 5

-6 -3 7 8

11 6 23 -1

Результат: imax=4.

a) Тестовый пример 2:

Файл matr.txt

4 4

-1 -2 -3 -6

-3 -9 0 -5

-6 -3 -7 -8

-11 -6 -23 -1

Результат: сообщение - Not A[i][j]>0 !

Результаты, выданные программой.

 

1. Тестовый пример1

input filename c:\matrix.txt

1 2 -3 -6

-3 -9 0 5

-6 -3 7 8

11 6 23 -1

imax= 4

PRESS ANY KEY!

 

2. Тестовый пример 2

input filename c:\matr.txt

-1 -2 -3 -6

-3 -9 0 -5

-6 -3 -7 -8

-11 -6 -23 -1

Not A[i][j]>0 !

PRESS ANY KEY!

 


Разработка программ сложной структуры

 

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

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

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

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

Передача данных в подпрограмму с помощью параметров. Формальные и фактические параметры

Как заголовок процедуры, так и заголовок функции может содержать список формальных параметров, который имеет следующий формат: (<описание параметра 1>; < описание параметра 2>;… < описание параметра n>) .

Использование процедур и функций

Задание. Определить наибольший общий делитель двух целых чисел. Постановка задачи. Входные данные:

Рекурсивные процедуры и функции

Рекурсивным называется объект, который частично определяется через самого себя. Рекурсивные определения используются во многих областях науки и,… Рассмотрим функцию определения факториала (n!); факториал – это произведение… (1) 1!=1;

Задание. Определить наибольший общий делитель двух целых чисел.

Постановка задачи.

Входные данные:

A , B – целые, положительные числа.

Выходные данные:

Nod – наибольший общий делитель A и B.

Метод решения: рекурсивный алгоритм Евклида.

 

Алгоритм. Выдача наибольшего общего делителя двух целых чисел.

Входные данные.

СКАЛЯР A , B – целые, положительные числа.

Выходные данные.

СКАЛЯР Nod – целое число.

Начало

A:=0

B:=0

ЦИКЛ_ПОКА(A<=0 ИЛИ B<=0)

Вывод(‘Input A,B : ’)

ввод(A,B)

КОНЕЦ_ЦИКЛА

Findnod(A,B,Nod)

Вывод(‘Nod(A,B)= ’,Nod)

Конец

 

Алгоритм. Процедура определения наибольшего общего делителя двух целых чисел (findnod).

Входные данные.

СКАЛЯР A , B – целые, положительные числа.

Выходные данные.

СКАЛЯР Nod – целое число.

Промежуточные данные.

СКАЛЯР R – целое число. {остаток от деления }

Начало

ЕСЛИ (A mod B <>0)

R:= A mod B

A:=B

B:= R

Findnod(A,B,Nod)

ИНАЧЕ

Nod:=B

КОНЕЦ_ЕСЛИ

Конец


Блок - схема программы

           
   
 
 
 
   
Рис. 9.12



Блок-схема процедуры findnod.

           
   
 
 
 
   
Рис. 9.13



Программа на языке Паскаль, использующая процедуру.


Program Exam7;

Var

A, B, Nod: integer;

procedure findnod (A, B: integer; Var Nod: integer);

Var R: integer;

Begin

If A mod B <>0 do

Begin

R:= A mod B;

A:=B; B:=R;

Findnod(A,B,Nod);

End

Else

Nod:=B;

End;

Begin A:=0; B:=0;

While (A<=0) or (B<=0) do begin

Writeln('Input A,B <>0 :');

Readln(A,B);

End;

findnod(A,B,Nod);

Writeln('Nod(A,B) = ',Nod);

Readln;

End.

 

Результаты тестирования.

1. Исходные данные:

A=84

B=36

Результат: Nod(A,B)=12

d) Тестовый пример 2:

A=84

B=56

Результат: Nod(A,B)=28

Результаты, выданные программой.

 

3. Тестовый пример1

Input A,B <>0 :

Nod(A,B) = 12

 

4. Тестовый пример 2

Input A,B <>0 :

Nod(A,B) = 28

 

Программа на языке Паскаль, использующая функцию.

Program Exam11;

Var

A, B, Nod: integer;

Function findnod (A, B: integer): integer;

Var R: integer;

Begin

R:=1;

While R<>0 do

Begin

R:=A mod B;

A:=B; B:=R;

End;

findnod :=A;

End;

Begin A:=0; B:=0;

While (A<=0) or (B<=0) do begin

Writeln('Input A,B <>0 :');

Readln(A,B);

End;

Nod := findnod(A,B);

Writeln('Nod(A,B) = ',Nod);

Readln;

End.

 

Результаты тестирования.

1. Тестовый пример 1

Исходные данные:

A=84

B=36

Результат: Nod(A,B)=12

2. Тестовый пример 2

Исходные данные:

A=84

B=56

Результат: Nod(A,B)=28

Результаты, выданные программой.

Тестовый пример1

Input A,B <>0 :

Nod(A,B) = 12

 

Тестовый пример 2

Input A,B <>0 :

Nod(A,B) = 28

 

 


Модули

 

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

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

Модуль имеет свой заголовок:

Unit <имя модуля>;

и два раздела: интерфейсную часть (interface) и исполняемую часть (implementation).

Общая структура модуля имеет следующий вид:

Unit <имя модуля>;

Interface

<объявления видимых объектов модуля: типов, констант, переменных, заголовков подпрограмм >

implementation

<описания скрытых объектов: процедур и функций>

begin

<операторы инициализации модуля[6]>

end.

 

Интерфейсная часть может включать следующие компоненты:

Interface

Uses <список используемых модулей >;

<раздел объявления констант (Const)>

<раздел объявления типов (Type) >

<раздел объявления переменных (Var)>

<раздел заголовков процедур и функций>.

Список используемых модулей содержит имена стандартных модулей, кроме модуля System, такие как Crt, Graph, Overlay, Dos, и имена модулей, созданных пользователем. Имена в списке разделяются запятыми.

В разделе реализации (implementation) содержатся описания процедур и функций, заголовки которых объявлены в интерфейсной части. Кроме того, в исполнительной части могут быть объявлены типы, константы, переменные, которые используются в подпрограммах, но должны быть недоступны пользователю. В конце текста модуля всегда записывает ключевое слово “end” с точкой.

Традиционные правила области действия глобальных и локальных переменных для модулей не выполняются. Языковая конструкция Unit (модуль) была специально включена в систему Borland Pascal для того, чтобы исключить влияние глобальных переменных, объявленных в главной программе, на описания подпрограмм, входящих в модули, которые эта программа использует.

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

 

Unit globals;

Interface

Const L=100;

Type Tvector = array[1..L] of integer;

Implementation

End.

 

В этом случае исполнительная часть implementation является пустой.

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

o function Vect_Max(Vect:TVector; N:byte): byte; - возвращает индекс максимального элемента массива из N элементов;

o function Vect_Min(Vect:TVector; N:byte): byte; - возвращает индекс минимального элемента массива;

o procedure Print_Vect(Vect:TVector; N:byte); - выдает все элементы массива на экран;

o procedure Vect_Inverse(Var Vect:TVector; i1,i2:byte); - меняет местами максимальный и минимальный элементы одномерного массива.

Кроме того, модуль Vector использует модуль глобальных описаний globals.


Текст модуля Vector.

unit Vector;

interface

Uses globals;

function Vect_Max(Vect:TVector; N:byte): byte;

function Vect_Min(Vect:TVector; N:byte): byte;

procedure Print_Vect(Vect:TVector; N:byte);

procedure Vect_Inverse(Var Vect:TVector; i1,i2:byte);

implementation

function Vect_Max(Vect:TVector; N:byte): byte;

Var Max:integer;

im,i: integer;

begin

Max:=Vect[1]; im:=1;

for i:=1 to N do

if Max<Vect[i] then begin

Max:=Vect[i]; im:=i;

end;

Vect_Max:=im;

end;

function Vect_Min(Vect:TVector; N:byte): byte;

Var Min:integer;

im,i: integer;

begin

Min:=Vect[1]; im:=1;

for i:=1 to N do

if Min>Vect[i] then begin

Min:=Vect[i]; im:=i;

end;

Vect_Min:=im;

end;

procedure Print_Vect(Vect:TVector; N:byte);

Var i: integer;

begin

writeln;

for i:=1 to N do write(Vect[i],' ');

end;

procedure Vect_Inverse(Var Vect:TVector; i1,i2:byte);

Var t: integer;

begin

t:=Vect[i1]; Vect[i1]:=Vect[i2]; Vect[i2]:=t;

end;

end.

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

 

Program Main;

Uses globals,vector;

Var A: TVector;

i,N:byte;

n1,n2:byte;

begin

writeln;

writeln(' Input N<=100');

readln(N);

writeln(' Input array A of N elements :');

for i:=1 to N do read(A[i]);

n1:=Vect_Max(A,N);

n2:=Vect_Min(A,N);

Vect_Inverse(A,n1,n2);

Print_Vect(A,N);

Readln;

end.

 

Тестовый пример. Результаты, выданные программой Main.

 

 

Input N<=100

Input array A of N elements :

1 2 3 4 5 64 7 8 9 19

 

64 2 3 4 5 1 7 8 9 19

 


Динамические структуры данных

Основные определения

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

Объявление и создание динамических структур данных. Указатели

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

Операции над указателями

 

Переменная типа «указатель» может находиться в трех состояниях:

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

2. Указатель содержит специальный, пустой адрес nil.

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

В неопределенном состоянии указатель бывает в начале работы программы до размещения переменной в памяти ЭВМ и присвоения указателю конкретного адреса или значения nil.

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

1. Объявление.

Type PInt = ^integer;

Var a,b: Pint;

Указатели a,b находятся в неопределенном состоянии.

2. Выделение памяти под переменную.

Type PInt = ^integer;

Var a,b: Pint;

………………………….

New(a); New(b);

Указатели a, b принимают значения адресов распределенной под неименованные переменные памяти. Обращение к этим переменным осуществляется с помощью операции косвенной адресации; a^, b^ – значения динамически размещенных переменных.

3. Присвоение указателю значения адреса нединамической переменной.

Var

P: ^char;

P1: ^char;

ch: char;

…………….

P:=@ch; { @ - операция определения адреса }

…………….

New(P1); ….. P:=P1; {присвоение указателю значения другого указателя }

Присвоение указателю значения возможно двумя способами:

· с помощью операции @ определения адреса другой переменной;

· с помощью присвоения указателю значения другого указателя.

4. Занесение информации по адресу, хранимому в переменной типа «указатель»
a^:=^b; или
a^:=2;

5. Освобождение памяти.

Dispose(a);

Указатель a переходит в неопределенное состояние. Различие между состоянием nil и неопределенным состоянием состоит в следующем. Если два указателя p1 и p2 имеют значение nil, то результат операции сравнения p1=p2 есть true. Если указатели p1 и p2 находятся в неопределенном состоянии, то их невозможно сравнивать.

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

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

 

Программа создания и обработки линейного списка

Линейный список – это структура данных, представляющая собой последовательность компонент, связанных между собой адресами, как показано на рис. 1. … PN   Информ. Поле1 Адрес 2-го элемента

Пример программы создания и обработки линейного списка.

program Project2;

{$APPTYPE CONSOLE}

uses

Windows;

type TPtr=^TElem;

TElem=record

Inf:integer;

Next:TPtr;

end;

Var Beg: TPtr; Value: integer; Rejim: byte;

Procedure Init_list(Var P: TPtr);

Begin P:=nil; end;

 

 

Procedure Add_list(Var P: TPtr);

Var PT,TPR,Prev:TPtr; Prizn: byte;

begin

write('Input Value: '); read(Value);

if P=nil then begin New(TPR); P:=TPR;

TPR^.Inf:=Value; TPR^.Next:=nil;

write('First element of list is created - ',Value);

end

else begin PT:=P; PREV:=nil; Prizn:=0;

while PT<>nil do

begin if Value<PT^.Inf then begin

if PREV=nil then begin

New(TPR); P:=TPR; TPR^.Inf:=Value;

TPR^.Next:=PT;

write('Element ',Value,' added before first element'); end

else begin

New(TPR); PREV^.Next:=TPR; TPR^.Inf:=Value;

TPR^.Next:=PT;

Write('Element ',Value, ' is added between two other elements ');

end;

Prizn:=1; break;

end;

PREV:=PT; PT:=PT^.Next;

end;

if Prizn=0 then begin

New(TPR); TPR^.Inf:=Value;

TPR^.Next:=nil; PREV^.Next:=TPR;

write('Element ',Value, ' is added after last element');

end; end;

end;

 

Procedure Del_Elem(Var P: TPtr);

Var

PT,TPR,Prev:TPtr; Prizn: byte;

begin

if P=nil then write('list is empty!!!')

else begin write('Input value: '); read(Value);

PT:=P; PREV:=nil; Prizn:=0;

while PT<>nil do begin

writeln(PT^.Inf);

if Value=PT^.Inf then begin

if PREV<>nil then begin

PREV^.Next:=PT^.Next; Prizn:=1;

write('Element is deleted '); break;

end

else begin P:=PT^.Next; Prizn:=1;

write('Element is deleted '); break;

end;

Dispose(PT);

end;

PREV:=PT; PT:=PT^.Next;

end;

if Prizn=0 then write('Element is not founded ' );

end;

end;

 

Procedure Display_list(P: TPtr);

Var

PT:TPtr; i: byte;

begin

i:=0; PT:=P;

if P=nil then begin write('list is empty!!!'); exit; end;

Writeln; write(' List =[');

while PT<>nil do

begin i:=i+1;

write(PT^.Inf,' '); PT:=PT^.Next;

end;

write(']'); write(' Number of elements = ',i);

end;

 

begin

while True do

begin

writeln;

write('0 -- Exit; '); write('1 -- Create; '); write('2 -- Display; ');

write('3 -- Add; '); writeln('4 -- Delete; '); writeln('Input option (0 -- 4)');

readln(Rejim);

case(Rejim) of

0: begin readln; exit; end;

1: Init_list(Beg);

2: Display_list(Beg);

3: Add_list(Beg);

4: Del_Elem(Beg)

else write('Error!!! ')

end; end; end.


Результаты работы программы.

Input option (0 -- 4)   0 -- Exit; 1 -- Create; 2 -- Display; 3 -- Add; 4 -- Delete;

Приложение. Контрольные вопросы

 

1. Структура ПЭВМ. Назначение центральных и внешних устройств ПЭВМ.

2. Принципы фон Неймана функционирования ЭВМ.

3. Понятие алгоритма. Свойства алгоритма.

4.Этапы разработки программного обеспечения. Этап анализа и уточнения требований к программе. Спецификация программы.

5.Этап проектирования программы. Формы представления алгоритма решения задачи.

6.Формы представления алгоритмов. Блок-схемы.

7. Формы представления алгоритмов. Псевдокод. Базовые операции и структуры алгоритмов.

8.Типы алгоритмических структур.

9.Язык Паскаль. Характеристика языка. Алфавит. Лексемы. Ключевые слова.

10. Представление арифметических констант на языке Паскаль. Десятичные и шестнадцатеричные целые константы. Вещественные числа.

11. Структура программы на языке Паскаль. Назначение разделов программы.

12. Понятие типа данных. Стандартные, предопределенные типы данных. Классификация типов.

13.Константы, переменные и их объявление. Основные скалярные типы данных. Отрезки типов.

14.Арифметические операции. Выражения. Последовательность выполнения операций. Приоритеты операций.

15.Логические константы и переменные. Логические операции и операции отношения. Логические выражения.

16.Стандартные арифметические функции. Примеры их использования.

17.Операторы языка Паскаль. Простые операторы. Оператор присваивания. Оператор вызова процедуры. Оператор перехода.

18.Стандартный ввод/вывод данных. Процедуры read, readln, write и writeln.

19.Структурные операторы языка Паскаль. Составной оператор.

20. Операторы управления. Условные операторы if и if-else.

21. Оператор множественного выбора case.

22. Оператор цикла с заданным числом повторений.

23. Операторы цикла с выходом по условию.

24. Структурные типы в языке Паскаль. Классификация структурных типов.

25. Одномерные массивы. Описание типа-массив, описание переменной типа массив. Инициализация массивов, доступ к элементам массива.

26. Двумерные массивы. Описание типа-массив, описание переменной типа массив. Инициализация массивов, доступ к элементам массива.

27. Записи: описание типа-запись, переменные типа-запись, доступ к элементам записей.

28. Записи с вариантами: описание типа-запись, переменные типа-запись, доступ к элементам записей.

29. Множества: описание типа, переменных и констант типа-множество. Операции над множествами.

30. Файлы. Объявление типа-файл и файловой переменной. Связь файловой переменной с физическим файлом. Общая структура программы обработки файлов.

31. Текстовые файлы. Стандартные процедуры и функции для работы с ними.

32. Типизированные файлы. Процедуры ввода/вывода для работы с ними.

33. Нетипизированные файлы. Процедуры ввода/вывода BlockRead и BlockWrite для работы с ними.

34. Разработка программ сложной структуры. Определение подпрограммы, процедуры и функции.

35. Область действия идентификаторов при использовании процедур и функций. Локальные и глобальные имена.

36. Способы передачи параметров подпрограммам. Формальные и фактические параметры.

37. Подпрограммы-процедуры. Структура описания процедуры.

38. Подпрограммы-функции. Структура описания функции.

39. Массивы- параметры процедур и функций.

40. Рекурсивные процедуры и функции.

41. Модули. Назначение модулей. Структура описания модуля.

42. Несвязанные динамические данные. Описание и использование.

43. Указатели. Объявление и использование. Операции над указателями.

44. Связанные динамические данные. Определение линейного списка, очереди и стека.

45. Связанные динамические данные. Пример программы создания линейного списка.

46. Обработка символьной информации. Символьные и строковые константы. Переменные типа string, стандартные процедуры и функции для работы с ними.

Литература

1) Фигурнов В.Э. IBM PC для пользователя. Издания 4-6.

2) Информатика: учебник – 3-е переработанное издание/ под ред. Н.В. Макаровой.- М: Финансы и статистика, 2004. – 768 с.

3) Основы современных компьютерных технологий: учебное пособие/ под ред. Проф. Хомоменко А.Д. – СПб.: Корона, принт, 1998.- 448 с.

4) Экономическая информатика: учебник / под ред. В.П. Косарева и Л.В. Еремина.- М.: Финансы и статистика, 2002. – 592 с.

5) Марченко А.И Программирование в среде Borland Pascal 7.0 Киев: Юниор, 1996.- 480 с.

6) Вирт Н. Алгоритмы и структуры данных. - М.: Мир, 1989


 

КАРПОВИЧ Елена Евгеньевна

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

Учебное пособие

 

 

Редактор Гаврилова Т.Д.

Технический редактор Аракелян Г.Ц.

 

 

Тем. план 2005 г., поз. 251

 

Подписано в печать 03.10.2005 г. Формат 60x90/16

 

Объем 9,5 печ. л. Тираж 200 экз. Заказ №

 

Типография Московского государственного горного университета

Ленинский проспект,6

 


[1] CASE-технологии в данном учебном пособии подробно не рассматриваются.

[2] Схемы применения редакторов связей в данном учебном пособии не рассматриваются.

[3] Базовые операции и управляющие структуры алгоритмов описаны ниже в п. 3.2

 

[4] Здесь и в дальнейшем используются угловые скобки < > для описания синтаксиса языка Паскаль, в угловых скобках указывается смысл пользовательских элементов программы.

 

[5] Здесь имеется в виду версия Borland Pascal 7.0 для DOS или консольные приложения Delphi.

[6] Операторы инициализации объектов модуля могут отсутствовать.

[k1]Ение

[k2]Ение

[k3]Ение

[k4]Ение