Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

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




Структура любой программной единицы (программы, процедуры или функции) должна быть такой:;

<Объявление программной единицы>

{Раздел описаний}

BEGIN

{Раздел исполняемых операторов}

END <символ конца программной единицы>

Здесь «Объявление программной единицы> - заголовок программы, процедуры или функции; заголовок программы можно опускать без каких-либо последствий для программы; для процедур и функций наличие заголовка обязательно; <символ конца программной единицы> - символ «.» для программы или символ «;» - для процедуры и функции.

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

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

глобальные для процедуры или функции идентификаторы (см. гл. 8). Если программная единица использует идентификатор из интерфейсной части, какого-либо модуля (см. гл. 9), в начале программы в предложении USES необходимо указать имя этого модуля. Последнее не относится к идентификаторам, определенным в стандартном модуле SYSTEM, т.е. имя этого модуля в предложении USES указывать не нужно. Более того, модуль SYSTEM считается предварительно объявленным, поэтому объявление

Uses System;

компилятор расценит как попытку двойного объявления модуля SYSTEM и даст соответствующее сообщение об ошибке. В разделе описаний объявляются идентификаторы типов, объектов, констант, переменных, а также метки, процедуры и функции. Описанию типов и объектов должно предшествовать зарезервированное слово TYPE, описанию констант - CONST, переменных - VAR и меток - LABEL, например:

type

DigType = set of '0'.. '9';

StrType = string [40];

const

N = 100;

EPS = 1e-9;

var

x,y:real;

st:StrType;

label

1b1, 1b2;

В отличие от стандартного Паскаля разделы TYPE, CONST, VAR, LABEL могут следовать друг за другом в любом порядке и встречаться в разделе описаний сколько угодно раз.

Описание процедуры или функции заключается в указании заголовка этой процедуры (функции) и ее тела (подробнее см. в гл. 8).

Структура программных библиотек (модулей) описана в гл.9.

· Глава 4. ТИПЫ ДАННЫХ

o 4.1. Простые типы

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

§ 4.1.2. Вещественные типы

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

§ 4.2.1. Массивы

§ 4.2.2. Записи

§ 4.2.3. Множества

o 4.3. Строки

o 4.4. Совместимость и преобразование типов

Г л а в а 4

ТИПЫ ДАННЫХ

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

Турбо Паскаль характеризуется разветвленной структурой типов данных (рис.4.1).

Рис.4.1. Структура типов данных

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

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

ПРОСТЫЕ ТИПЫ

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

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

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

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

К порядковым типам можно также применять функции:

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

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

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

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

Например, если в программе определена переменная

var

с: Char;

begin

с:= '5';

end.

то функция PRED(C) вернет значение '4', а функция SUCC(C) - значение '6'.

Если представить себе любой порядковый тип как упорядоченное множество значий, возрастающих слева направо и занимающих на числовой оси некоторый отрезок, то функция PRED(X) не определена для левого, a SUCC(X) - для правого конца этого отрезка.

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

Таблица 4.1

Целые типы
Название Длина, байт Диапазон значений
Byte   0...255
ShortInt   -128...+127
Word   0...65535
Integer   -32768...+32767
LongInt   -2 147 483 648... +2 147 483 647

При использовании процедур и функций с целочисленными параметрами следует руководствоваться «вложенностью» типов, т.е. везде, где может использоваться WORD, допускается использование BYTE (но не наоборот), в LONGINT «входит» INTEGER, который, в свою очередь, включает в себя SHORTINT.

Перечень процедур и функций, применимых к целочисленным типам, приведен в табл.4.2. Буквами b, s, w, i, l обозначены выражения соответственно типа BYTE, SHORTINT, WORD, INTEGER и LONGINT, x - выражение любого из этих типов; буквы vb, vs, vw, vi, vl, vx обозначают переменные соответствующих типов. В квадратных скобках указывается необязательный параметр.

Таблица 4.2

Стандартные процедуры и функции, применимые к целым типам
Обращение Тип результата Действие
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) To же То же
Lo(i) " Возвращает младший байт аргумента
Lo (w) " То же
odd(l) Boolean Возвращает True, если аргумент - нечетное число
Random (w) Как у параметра Возвращает псевдослучайное число, равномерно распределенное в диапазоне 0...(w-l)
sgr (x) X Возвращает квадрат аргумента
swap (i) Integer Меняет местами байты в слове
swap (w) Word  

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

var

а: Integer;

х, у: Real;

begin

а:= 32767; {Максимально возможное значение типа INTEGER}

х:= а + 2; {Переполнение при вычислении этого выражения!}

у:= LongInt(а)+2; {Переполнения нет после приведения переменной к более мощному типу}

WriteLn(x:10:0, у:10:0)

end.

В результате прогона программы получим

-32767 32769

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

ord(False) = 0;

ord(True) = 1;

False < True;

succ(False)= True;

pred(True) = False.

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

var

1: Boolean;

begin

for 1:= False to True do....

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

Для кодировки используется код ASCII (American Standard Code for Information Interchange - американский стандартный код для обмена информацией). Это 7-битный код, т.е. с его помощью можно закодировать лишь 128 символов в диапазоне от 0 до 127. В то же время в 8-битном байте, отведенном для хранения символа в Турбо Паскале, можно закодировать в два раза больше символов в диапазоне от 0 до 255. Первая половина символов ПК с кодами 0...127 соответствует стандарту ASCII (табл. 4.3). Вторая половина символов с кодами 128...255 не ограничена жесткими рамками стандарта и может меняться на ПК разных типов (в прил.2 приведены некоторые распространенные варианты кодировки этих символов).

Таблица 4.3

Кодировка символов в соответствии со стандартом ASCII
Код Символ Код Символ Код Символ Код Символ
  NUL   BL   ®   '
  ЗОН   !   A   a
  STX   "   В   b
  ЕТХ   #   С   с
  EOT   $   D   d
  ENQ   %   E   e
  АСК   &   F   f
  BEL   '   G   g
  BS   (   H   h
  НТ   )   I   i
  LF   *   J   j
  VT   +   k   k
  FF   ,   L   i
  CR   -   M   m
  SO   .   N   n
  SI   /   О    
  DEL       p   P
  DC1       Q   q
  DC2       R   r
  DC3       S   s
  DC4       T   t
  NAK       U   u
  SYN       V   V
  ETB       w   w
  CAN       X   X
  EM       У   У
  SUB   :   z   z
  ESC   /   [   {
  FS   <   \   l
  GS   =   ]   }
  RS   >   ^   ~
  US   ?     п

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

Символ Код Значение
BEL   Звонок; вывод на экран этого символа сопровождается звуковым сигналом
НТ   Горизонтальная табуляция; при выводе на экран смещает курсор в позицию, кратную 8, плюс 1 (9, 17, 25 и т.д.)
LF   Перевод строки; при выводе его на экран все последующие символы будут выводиться, начиная с той же позиции, но на следующей строке
VT   Вертикальная табуляция; при выводе на экран заменяется специальным знаком
FF   Прогон страницы; при выводе на принтер формирует страницу, при выводе на экран заменяется специальным знаком
CR   Возврат каретки; вводится нажатием на клавишу Enter (при вводе с помощью READ или READLN означает команду «Ввод» и в буфер ввода не помещается; при выводе означает команду «Продолжить вывод с начала текущей строки»)
SUB   Конец файла; вводится с клавиатуры нажатием Ctrl-Z; при выводе заменяется специальным знаком
SSC   Конец работы; вводится с клавиатуры нажатием на клавишу ESC; при выводе заменяется специальным знаком

К типу CHAR применимы операции отношения, а также встроенные функции: СНR(В) - функция типа CHAR; преобразует выражение В типа BYTE в символ и возвращает его своим значением;

UPCASE(CH) - функция типа CHAR; возвращает прописную букву, если СН -строчная латинская буква, в противном случае возвращает сам символ СН, например:

var

cl,c2: Char;

begin

cl:= UpCase('s');

c2:= UpCase ('Ф');

WriteLn(cl,' ',c2)

end.

Так как функция UPCASE не обрабатывает кириллицу, в результате прогона этой

программы на экран будет выдано

S ф

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

typе

colors =(red, white, blue);

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

type

ТипМесяц=(янв,фев,мар,апр,май,июн,июл,авг,сен,окт,ноя,дек);

var

месяц: ТипМесяц;

begin

.......

if месяц = авг then WriteLn('Хорошо бы поехать к морю!');

.......

end.

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

type

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

var

month: TypeMonth;

begin

.......

if month = aug then WriteLn('Хорошо бы поехать к морю!');

.......

end.

Соответствие между значениями перечисляемого типа и порядковыми номерами этих значений устанавливается порядком перечисления: первое значение в списке получает порядковый номер 0, второе - 1 и т.д. Максимальная мощность перечисляемого типа составляет 65536 значений, поэтому фактически перечисляемый тип задает некоторое подмножество целого типа WORD и может рассматриваться как компактное объявление сразу группы целочисленных констант со значениями О, 1 и т.д.

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

type

colors = (black, red, white);

ordenal= (one, two, three);

days = (monday, tuesday, Wednesday);

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

ord(black)=0,..., ord(white)=2,

ord(one)=0,...ord(three)=2,

ord(monday)=0,...ord(Wednesday)=2.

Однако, если определены переменные

var

col:colors; num:ordenal;

day: days;

то допустимы операторы

col:= black;

num:= succ(two);

day:= pred(tuesday);

но недопустимы

col:= one;

day:= black;

Как уже упоминалось, между значениями перечисляемого типа и множеством целых чисел существует однозначное соответствие, задаваемое функцией ORD(X). В Турбо Паскале допускается и обратное преобразование: любое выражение типа WORD можно преобразовать в значение перечисляемого типа, если только значение целочисленного выражения не превышает мощное1™ перечисляемого типа. Такое преобразование достигается применением автоматически объявляемой функции с именем перечисляемого типа (см. п. 4.4). Например, для рассмотренного выше объявления типов эквивалентны следующие присваивания:

col:= one;

col:= colors(0);

Разумеется, присваивание

col:= 0;

будет недопустимым.

Переменные любого перечисляемого типа можно объявлять без предварительного описания этого типа, например:

var

col: (black, white, green);

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

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

Здесь <мин.знач. > - минимальное значение типа-диапазона;

<макс.знач.> - максимальное его значение.

Например:

type

digit = '0'..'9';

dig2= 48..57;

Тип-диапазон необязательно описывать в разделе TYPE, а можно указывать непосредственно при объявлении переменной, например:

var

date: 1..31;

month: 1..12;

Ichr: 'A'..'Z';.

При определении типа-диапазона нужно руководствоваться следующими правилами:

· два символа «..» рассматриваются как один символ, поэтому между ними недопустимы пробелы;

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

type

days = (mo,tu,we,th,fr,sa,su);

WeekEnd = sa.. su;

var

w: WeekEnd;

begin

.....

w:= sa;

.....

end;

то ORD(W) вернет значение 5, в то время как PRED(W) приведет к ошибке.

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

НIGН(Х) - возвращает максимальное значение типа-диапазона, к которому принадлежит переменная X;

LOW(X) -возвращает минимальное значение типа-диапазона.

Следующая короткая программа выведет на экран строку

-32768...32767

var

k: Integer;

begin

WriteLn(Low(k),'..',High(k))

end.

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

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

Таблица 4.4

Длина, байт Название Количество значащих цифр Диапазон десятичного порядка
  Real 11...12 -39...+38
  Double 15...16 -324...+308
  extended 19...20 -4951...+4932
  comp 19...20 -2*1063+1...+2*63-1

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

s e m

 

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

Мантисса m имеет длину от 23 (для SINGLE) до 63 (для EXTENDED) двоичных разрядов, что и обеспечивает точность 7...8 для SINGLE и 19...20 для EXTENDED десятичных цифр. Десятичная точка (запятая) подразумевается перед левым (старшим) разрядом мантиссы, но при действиях с числом ее положение сдвигается влево или вправо в соответствии с двоичным порядком числа, хранящимся в экспоненциальной части, поэтому действия над вещественными числами называют арифметикой с плавающей точкой (запятой).

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

В некоторых случаях бывает необходимо отключить автоконтроль. Для этого перед запуском Турбо Паскаля следует дать такую команду ДОС:

set 87=N

команда

set 87=Y

напротив, включает автоконтроль - эта команда активна по умолчанию.

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

Например, если «машинное эпсилон» (см. пример 2.6 в гл.2) вычисляется с помощью такой программы:

{$N+,E+}

type

RealType = Real:

var

epsilon: RealType;

begin

epsilon:= 1;

while 1+epsilon/2 > 1 do

epsilon:= epsilon/2;

WriteLn(epsilon)

end.

то независимо от объявления типа REALTYPE (он может быть SINGLE, REAL, DOUBLE или EXTENDED) на печать будет выдан результат

1.08420217248550Е-0019

что соответствует типу EXTENDED. Происходит это по той причине, что все операнды вещественного выражения 1 + epsilon/2 в операторе WHILE, перед вычислением автоматически преобразуются к типу EXTENDED. Чтобы получить правильный результат (например, для типа REALTYPE = REAL он будет 9. 09494701772928Е-0013), программу необходимо изменить следующим образом:

{$N+,E+}

type

RealType= Real;

var

epsilon, epsl:RealType;

begin

epsilon:= 1;

repeat

epsilon:= epsilon/2;

epsl:= 1 + epsilon

until epsl = 1;

WriteLn(2*epsilon)

end.

Следует учесть, что тип REAL оптимизирован для работы без сопроцессора. Если Ваш ПК оснащен сопроцессором, использование типа REAL приведет к дополнительным затратам времени на преобразование REAL к EXTENDED. Поэтому никогда не используйте REAL на ПК с сопроцессором, т.к. дополнительные затраты времени на преобразование типов могут свести на нет все преимущества сопроцессора. При разработке программ, критичных ко времени счета, следует заменять его типами SINGLE или DOUBLE: по сравнению с типом REAL скорость вычислений на машинах с сопроцессором в этом случае увеличивается в 2...3 раза. Если в ПК нет арифметического сопроцессора, скорость обработки данных всех вещественных типов приблизительно одинакова.

Особое положение в Турбо Паскале занимает тип СОМР, который трактуется как вещественное число без экспоненциальной и дробной частей. Фактически, СОМР - это «большое» целое число со знаком, сохраняющее 19...20 значащих десятичных цифр (во внутреннем представлении СОМР занимает 8 смежных байт). В то же время в выражениях СОМР полностью совместим с любыми другими вещественными типами: над ним определены все вещественные операции, он может использоваться как аргумент математических функций и т.д. Наиболее подходящей областью применения типа СОМР являются бухгалтерские расчеты: денежные суммы выражаются в копейках или центах и действия над ними сводятся к операциям с достаточно длинными целыми числами.

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

Таблица 4.5

Стандартные математические функции Турбо Паскаля
Обращение Тип параметра Тип результата Примечание
abs (x) Real, Integer Тип аргумента Модуль аргумента
АrсТаn (х) Real Real Арктангенс (значение в радианах)
cos (х) To же То же Косинус, угол в радианах
ехр (х) " " Экспонента
frас (х) " " Дробная часть числа
int(x) " " Целая часть числа
ln(x) " " Логарифм натуральный
Pi - " л = 3.141592653...
Random - " Псевдослучайное число, равномерно распределенное в диапазоне 0...[1]
Pandom(x) Integer Integer Псевдослучайное целое число, равномерно распределенное в диапазоне 0...(х-1)
Randomize - - Инициация генератора псевдослучайных чисел
sin(x) Real Real Синус, угол в радианах
sqr (x) To же То же Квадрат аргумента
sqrt (x) " " Корень квадратный
Поделиться:





Читайте также:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...