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

Вид материалаДокументы

Содержание


Структурируемости и читаемости текста программы –
Инкапсуляция данных
Инкапсуляция программного кода
Примеры неструктурных языков
Примеры структурных языков
Повышение надежности работы программ
Буквы: ABCD...XYZ — заглавные (прописные), abcd...xyz — строчные, а также знак _ — подчеркивание. Цифры
Составные специальные символы
Символы формирования текста
{realcompatibility on}
Бинарные неполиморфные целочисленные
Унарные полиморфные
Составной оператор
Совместимые по присваиванию
Операция "равно" (=)
Операция "не равно" ()
Операция "меньше или равно" (
Объединение множеств (+).
Разностью множеств (-).
Неформатный вывод в файл
...
Полное содержание
Подобный материал:
  1   2   3   4   5

Объектно-ориентированное программирование

с примерами на Object PASCAL

(72 часа)

Вадим Валериевич Монахов, доцент кафедры вычислительной физики СпбГУ

Введение



1.1. Основной принцип структурного программирования

Структурное программирование — это метод программирования, опирающийся на структурную организацию программы.

Основной принцип структурного программирования - обеспечить максимальное соответствие структуры текста программы логике решаемой проблемы.


Способы реализации основного принципа структурного программирования:

1) Структурируемости и читаемости текста программы – отступы, обозначения, группировка частей текста.

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

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

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

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


Примеры неструктурных языков:

Ассемблер — не удовлетворяет:

  1. "Читаемость" — из-за плохой читаемости программы, отсутствия структурируемости текста;
  2. "Отлаживаемость" — полное отсутствие;
  3. "Структурные типы" — полное отсутствие;
  4. "Инкапсуляция кода" — полное отсутствие;
  5. "Инкапсуляция времени выполнения" — полное отсутствие.

FORTRAN — не удовлетворяет:

  1. "Читаемость" — из-за необходимости часто использовать оператор goto, неразвитости блочной организации текста программы, позиционной зависимости кода;
  2. "Отлаживаемость" — из-за отсутствия пользовательских типов и, что более критично — слабого контроля типов. С этим связано существование недиагностируемых ошибок типа DO7I=1.10, когда в операторе цикла вместо "," поставили ".", в результате чего "Voyager" пролетел мимо Венеры;
  3. "Структурные типы" — отсутствие структурных типов данных (кроме массивов);
  4. "Инкапсуляция кода" — почти отсутствует, так как нет модулей, вложенности блоков программного кода (подпрограммы не могут быть вложены друг в друга) и крайне плохо организованных интерфейсов между блоками кода (операторы block data и т.д.);
  5. "Инкапсуляция времени выполнения" — полное отсутствие.

В FORTRAN-77 появились возможности, преодолевающие ряд перечисленных недостатков. FORTRAN-99 пошел еще дальше, однако многие недостатки сохранялись, а новые возможности сделали его достаточно сложным и непоследовательным.


Примеры структурных языков:

С:

  1. "Читаемость" — удовлетворительно (не очень хорошая читаемость из-за наличия макросов машинной ориентации языка с выражениями типа y+=x );
  2. "Отлаживаемость" —удовлетворительно не очень хороший синтаксис языка, поэтому много ошибок не отслеживается при компиляции (например, "," вместо ";" в функции "for", а также ошибки, возникающие из-за правил автоматического приведения типов). Наличие указателей с соответствующими правилами присваивания часто приводит к фатальным ошибкам.
  3. "Структурные типы" —хорошо;
  4. "Инкапсуляция кода" —хорошо. Не очень удачно организована модульность;
  5. "Инкапсуляция во время выполнения" — полное отсутствие.

C++:

То же, что C, 2) несколько усовершенствован (однако переусложнен). Имеется объектная модель, расширяющая 1), 2), 3), 4). Правда, имеется дефект в ограничении правила видимости объектов (правила видимости могут быть несанкционированно изменены).

5)"Инкапсуляция времени выполнения" — наличие обработки исключительных ситуаций (exceptions).

PASCAL:

  1. "Читаемость" — хорошо;
  2. "Отлаживаемость" — хорошо. Проблемы: правила автоматического приведения типов, работа с указателями, явное приведение типов, вариантная запись;
  3. "Структурные типы" — хрошо;
  4. "Инкапсуляция кода” —удовлетворительно: отсутствуют модули (в стандарте языка) и пакеты; Turbo Pascal лучше удовлетворяет "4)", хоть и имеет не очень продуманные интерфейсы и правила видимости между модулями;
  5. "Инкапсуляция времени выполнения" — полное отсутствие.

Object Pascal (начиная с Delphi 2.0) (без явного применения объектов):

Имеется объектная модель, расширяющая 1), 2), 3), 4). Кроме того, начиная с Delphi 3.0 появились пакеты.

5)"Инкапсуляция времени выполнения" —

а) наличие обработки исключительных ситуаций (exceptions);

b) работа с подпроцессами (threads).

Java:

  1. "Читаемость" — удовлетворительно. Недостатки: переусложненность ряда простых в принципе действий из-за чрезмерного увлечения объектным подходом (например, при действиях с файлами и строками); "рецидивы", ведущие происхождение от С (операнды типа y+=x, функции for,?: и т.п. Зато макросы отсутствуют!). Наличие большого числа маленьких подпрограмм (классов) без возможности их объединения в единое целое.
  2. "Отлаживаемость" —отлично, за исключением правил автоматического приведения типов (указатели ликвидированы!);
  3. "Структурные типы" —хорошо;
  4. "Инкапсуляция кода" —хорошо. Сложность: отсутствие вложенных программ. В некоторой степени решено, начиная с Java 1.1 – вложенные классы;
  5. "Инкапсуляция во время выполнения" — хорошо. Имеются:
  1. обработка исключительных ситуаций;
  2. работа с подпроцессами (threads).

" onclick="return false">
1)”Читаемость” – удовлетворительно ( С-образен);

2)”Отлаживаемость” – неудовлетворительно (свободная типизация и при этом слабая типизация), крайне плохая диагностика ошибок;

3)”Структурные типы” – хорошо (благодаря объектной модели);

4)”Инкапсуляция кода” – удовлетворительно (нет модулей, пакетов; вложенные функции появились только в " onclick="return false">
5)”Инкапсуляция времени выполнения” – удовлетворительно для JS в IE4 и последующих (есть обработка исключений), неудолетворительно – для других бразеров.


1.2. Основные задачи структурного программирования

Структурное программирование предназначено для решения трех основных задач:
  1. Повышение эффективности разработки программ: а) увеличение скорости написания программ; б) увеличение качества их сопровождения (внесения усовершенствований, исправления ошибок); в) уменьшение стоимости разработки; г) обеспечение возможности групповой работы с проектом; д) обеспечение возможности проектирования ПО (software engineering).
  2. Повышение надежности работы программ. Никому не нужна дешевая, мгновенно написанная и занимающая мало ресурсов программа, которая работает очень быстро, но с ошибками. Из программистского фольклора: “Беремся написать вам ПО : 1. Бысро 2.дешево 3.надежно. – Два из трех.
  3. Повышение эффективности работы программ: увеличение скорости их выполнения, расширение функциональных и сервисных возможностей программ, а также уменьшение их ресурсоемкости (размеров программного кода, объема используемой оперативной и дисковой памяти).

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


1.3. Основные принципы объектно-ориентированного программирования (ООП)

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

I. Инкапсуляция: объединение данных с процедурами и функциями в единый блок программного кода (данные и методы работы с ними рассматриваются как поля объекта).

II. Наследование (наличие экземпляров класса; потомки, прародители, иерархия).

III. Полиморфизм (единое имя для некого действия, которое по-разному осуществляется для объектов иерархии).

Компонентное программирование:

Реализация объектов в виде независимо распространяемых исполняемых модулей. Известны 2 типа компонентов:

А) Компоненты конкретного языка программирования (Visual BASIC, Object PASCAL, Java). Предназначены преимущественно для поддержки средств визуального проектирования

Б) Компоненты, поддерживаемые на уровне ОС (компоненты Activex, .NET).


Основы языка Object PASCAL.

2.1. Алфавит языка PASCAL. Идентификаторы.

Основной алфавит языка PASCAL состоит из латинских букв и цифр.

Буквы:

ABCD...XYZ — заглавные (прописные),

abcd...xyz — строчные,

а также знак _ — подчеркивание.

Цифры:

0123456789

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

Замечание:

а) Компиляторы PASCAL не являются регистро-чувствительными (case sensitive), т.е. не различают прописные и строчные буквы, т.е. I1 и i1 — одинаковые идентификаторы. Это отличает PASCAL от C, C++, " onclick="return false">
б) Национальные алфавиты можно использовать только в строковых выражениях.


2.2. Простые и составные специальные символы, используемые на ПК.

Перечисленный ниже набор несколько расширяет стандарт PASCAL, однако на ПК является стандартом de facto.

Простые специальные символы:

+

Плюс – “сложение”



Минус – “вычитание”

*

Звездочка – “умножение”

/

косая черта (slash) – “деление”

=

Равно (Замечание: в C-образных языках в качестве этого знака используется = =)

>

Больше

<

Меньше

[

левая квадратная скобка – открытие индекса массива

]

правая квадратная скобка – закрытие индекса массива

(

левая круглая скобка

)

правая круглая скобка

{

левая фигурная скобка – открытие комментария

}

правая фигурная скобка – закрытие комментария

@

коммерческое a (“эт”) – знак адресации

.

Точка

,

Запятая

:

Двоеточие

;

точка с запятой

'

апостроф (одиночная кавычка) – открытие и закрытие строки символов

"

двойные кавычки – не имеет специального назначения

#

номер (hash) - не имеет специального назначения

$

знак доллара – используется в 16-ричной нотации чисел

\

обратная косая черта (backslash) - не имеет специального назначения



"шляпка" – используется для работы с указателями

~

Тильда - не имеет специального назначения




знак пробела (невидимый)




знак табуляции (невидимый)


Составные специальные символы:

:=

Присваивание ( в C-образных языках и BASIC используется знак “ = “)

<>

не равно( в C-образных языках используется знак “! =” )

..

Диапазон значений ( в C-образных языках и BASIC отсутствует)

(*

Начало комментария. Замена знаку “{“, но может быть только в комбинации с “*)” - в C-образных языках используется знак “/*”

*)

конец комментария. Замена знаку “}”, но может быть только в комбинации с “(*” - в C-образных языках используется знак “*/”

(.

Замена знаку “[“, но может быть только в комбинации с “.)” Редко используется.

.)

Замена знаку “]”, но может быть только в комбинации с “(.” . Редко используется.

//

Однострочный комментарий.

Специальные символы (простые или составные) служат разделителями в выражениях языка PASCAL. Они не могут входить с состав идентификаторов.

Отсутствующие в Object PASCAL символы, имеющиеся в С-образных языках:

- возведение в степень (начиная с Delphi 4 в Object PASCAL есть функция power)

<< - левый побитовый сдвиг (“shl” в Object PASCAL)

>> - правый побитовый сдвиг (“shr” в Object PASCAL)

>>> - правый побитовый сдвиг с сохранением знака отрицательного числа ( в Object PASCAL отсутствует)


Символы формирования текста:

Знак пробела , табуляции , символы перевода на новую строку , конца страницы , конца файла и другие управляющие символы. Действуют при просмотре исходных текстов языка Object PASCAL и за исключением ряда случаев — в строковых выражениях.


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

Целые типы

Byte: 0..255 — байтовый (1 байт)

ShortInt: -128..127 — короткое целое (1 байт)

Word: 0..65535 — 16-ричное слово (2 байта)

Integer(в C, C++,…-int) — целые. Начиная с Delphi3 по умолчанию идентичен longInt – см.далее

LongInt: -2147483648..2147483647 — длинное целое (диапазон примерно

-2e9..2e9, размер 4 байта)

LongWord – 32-битные без знака (4байта)

Int64 – 64-битные со знаком (8 байт) – имеют особенности в правилах приведения типа

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

Real(в C - float) — вещественные, (изначально был 6 байт, 11..12 значащих цифр мантиссы): 0.0, 0.1, 1e6,2.9e-39, -1.7e38

Начиная с Delphi3 по умолчанию идентичен Double (см. далее)

Double: 5.0e-324..1.7e308 — двойная точность (8 байт, 15..16 значащих

цифр мантиссы)

Extended: 1.9e-4951..1.1e4932 — расширенная точность (10 байт, 19..20

значащих цифр мантиссы)

Булевский (логический) тип

Boolean (1 байт): величины этого типа принимают только значения true или false.Во всех C-образных языках кроме Java идентичен байтовому типу

Символьный (литерный) тип

Char (1 байт): один символ. 'A', 'b', '*', ' ', '/'. (Существует в Java, в других C-образных языках идентичен байтовому типу. В Java константы символьного типа пишутся в двойных кавычках: “A”, “b” и т.д).

Строковый тип

String (не менее 4 байт): произвольное число символов (от 0 до 2e9). 'A', 'abcd', 'мама моет раму', ' '. Работа со строками в Object PASCAL не имеет аналогов по мощности и удобству в других языках программирования

Двоичное представление целых положительных чисел



Двоичное представление целых отрицательных чисел



Двоичное представление вещественных чисел

Двоичные дроби. … Мантисса и логарифм…

2.4. Особенности работы с некоторыми типами данных

  1. 64-битовые целые

Описание:

Var a:Int64;

Значения — 263 … 263 -1 - знаковые 64-битные.

Преобразование обычного числа в 64-битовое – с помощью функции Int64.

Примеры задания 64-битных статических переменных (о том, что это такое, см. :

const Num64=Int64(17);

const Num64b:Int64=17;

const Num64c=3000000000;

Вызовы осуществляются только с 64-битными числами во всех частях выражения:

a:=a+Int64(1);
  1. 32-битовые без знака — Longword;

0..4294967295 (то есть чуть больше 4*109 ) — то есть то же, что Cardinal;
  1. Изменения в типе Real

Был 48-битовым, теперь идентичен 64-битовому Double. Для совместимости можно использовать тип Real48 либо ставить опцию компилятору

{REALCOMPATIBILITY ON}

2.5. Арифметические операторы.

Бинарные полиморфные (тип результата определяется по правилам приведения типов,

см. далее):

+ сложение (все целые и вещественные типы, строковые типы, множества).

Пример: a+b

- вычитание (все целые и вещественные типы, множества): a-b

* умножение (все целые и вещественные типы, множества): a*b

/ деление (все целые и вещественные типы, результат — вещественный):

a/b


Бинарные неполиморфные целочисленные:

div — целочисленное деление. Пример: a div b

mod — остаток от целочисленного деления a mod b

(в C-образных %):

and — побитовое "И" (в C-образных &) a and b

or — побитовое "ИЛИ"(в C-образных | ) a or b

xor — побитовое "исключающее ИЛИ"(в C-образных ) a xor b

shl — побитовый сдвиг влево(в C-образных <<) a shl b

shr — побитовый сдвиг вправо(в C-образных >>) a shr b


Унарные полиморфные:

+ сохранение знака (целые и вещественные типы). Пример: +a
  • изменение знака на противоположный(целые и вещественные типы).

Пример: -a


Унарные целочисленные:

not побитовое "НЕ" (целые типы). Пример: not a


2.6. Логические операторы и операции отношения.

Логические операторы:

and логическое "И". Пример: a and b

or логическое "ИЛИ": a or b

xor логическое "исключающее ИЛИ": a xor b

not логическое "НЕ": not a

Операции отношения (результат — типа boolean):

= равно. Пример: A=B

<> не равно: A<>B

> больше: A>B

< меньше: A
>= больше или не равно: A>=B

<= меньше или не равно: A<=B

in принадлежность множеству: A in B


2.7. Потеря точности, потеря порядка и переполнение при арифметических операциях.

Пусть x1 – арифметическая переменная real, x2 – вещественная extended. Тогда выполнение присваиваний x2:=1+1e-14 даст 1.00000000000001, а x1:=1+1e-14 даст 10000000000000,т.к. числа real имеют всего 12 значащих цифр мантиссы. После этого выражение x2:=x2-1 даст 1e-14, а выражение x1:=x1-1 даст 0. Это потеря точности. Если мы имеем выражение типа a+b-c, где a очень близко к c, а b<

2.8. Структура простейшей программы.

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

program MyProg1; //имя файла должно быть MyProg1.pas

var a,b,c: integer; {начало раздела переменных – зарезервированное

слово var}

a1,b1: real;

x: integer;

goodResult: boolean; //конец раздела описания переменных

begin //начало тела программы

a:=1;

b:=a+5;

a1:=b/sin(b-a);

x:=round(a1);

goodResult:=(x<2);

end. //конец тела программы, завершается точкой

Комментарии компилятором игнорируется.


2.9. Простейшие операторы языка Object PASCAL

2.9.1. Пустой и составной операторы.

Операторы в языке PASCAL разделяется символом ";".

Пустой оператор — это просто пустая строка (или эквивалентная ей последовательность пробелов и переносов на новую строку), после которой стоит ";". Он ничего не делает. Иногда использовался для того, чтобы поставить перед ним метку для использования в операторе goto.

Составной оператор — блок кода от begin до end:

begin

последовательность простых или составных операторов

end;

Используется там, где по синтаксису языка PASCAL может стоять один оператор, а надо использовать последовательность операторов.

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


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

Этот оператор требует наличия метки (label), на которую и производится переход. Идентификатор метки — либо целое число, меньшее <65367, либо буквенно-численный идентификатор; обычно используют число.

program MyProg2;

label 1;

var i: integer;

begin

...

if...then goto1;

...

1:...

...

end.

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


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

if условие then оператор; — первая форма

В C-образных if (условие) оператор;

if условие then оператор1

else оператор2; — вторая форма

В C-образных if (условие) оператор;

Else оператор;

Пример:

if a
then a:=a+1

else (if a=b

then a:=a+1

else

begin

a:=a+1;

b:=b+1

end

);

Надо отметить, что после then должен стоять только один оператор, а не последовательность операторов. Поэтому запись оператора в виде

if условие then оператор1;

else оператор2;

недопустима, т.к. символ ”;”, стоящий после оператора1, рассматривается как пустой оператор, и поэтому между then и else стоят два оператора, а может быть только один. Хотя бы и составной, ограниченный операторными скобками begin и end.

В случае последовательности операторов типа:

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

имеющийся else относится к последнему then, поэтому лучше отформатировать текст так:

if условие1

then if условие2

then оператор1

else оператор2;

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

Пример неправильного стиля оформления:

if условие1

then if условие2

then оператор1

else оператор2;

Этот стиль подталкивает к логической ошибке при чтении программы. Надо отметить, что сама возможность такой ошибки связана с непродуманностью синтаксиса языка PASCAL (в том числе Object Pascal). Другой вариант ошибки, связанный с синтаксисом PASCAL, может быть вызван лишним символом “;” после then. Так, строки

If условие then; оператор1;

И

If условие then оператор1;

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

If условие then;

Оператор1;

Т.е. при выполнении условия выполнится пустой оператор, а оператор1 будет выполнен всегда.


2.9.4. Оператор выбора case.

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

сase выражение of

значение1:оператор1;

...

значение2,значение3,...,значениеN:оператор2;

начальное значение..конечное значение:оператор3

else оператор

end;

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

Часть с else является необязательной.

Пример:

case (a mod b) of

0: i:=0;

1: i:=1;

2,4,6,8: i:=2;

10..100: begin

i:=3;

a:=a div10

end

else i:=4

end {/case};

. . .

В C-образных языках для аналогичных целей применяется конструкция

switch (выражение)

{

case значение1: оператор1;

……………………………

case значение N: оператор N;

default: оператор;

}


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

Имеется две формы синтаксиса оператора.

1) Цикл от меньшего к большему значению:

for переменная:=значение1 to значение2 do оператор; Значения должны быть перечисляемого типа. Если значение2 меньше значения1, цикл не выполняется ни разу, если они равны – один раз.

2) Цикл от большего к меньшему значению:

for переменная:=значение2 downto значение1 do оператор; - цикл от большего значения к меньшему. Шаг по умолчанию равен 1.

Примеры:

1) x:=1; for i:=1 to n step m do x:=x*i;

2) for i:=10 downto 1 do writeln(i);

3) for s='d' to 'z' do

begin

...

end.

C-образные языки:

for (инициализация; условие продолжения; изм. Счетчиков)

{тело цикла};

BARSIC: for(i=i1..i2)do(…);

for(i=a..b, step=s)do(…);


2.9.6. Оператор цикла while...do – цикл с предусловием.

while условие do оператор;

Пока условие сохраняет значение true — в цикле выполняется оператор, иначе — действие цикла прекращается. Если условие с самого начала false, цикл сразу прекращается, и тело цикла – оператор – не выполнится ни разу.

Пример:

i:=1; x:=1;

while i<=n do

begin

x:=x*i;

i:=i+1

end;


2.9.7. Оператор цикла repeat...until – цикл с постусловием.

repeat

оператор1; {тело цикла}

оператор2; {тело цикла}

...

операторN {тело цикла}

until условие выхода;

Если условие принимает значение true, цикл прекращается. Тело цикла выполняется до проверки условия, поэтому оно всегда выполнится хотя бы один раз.

Пример:

i:=0; x:=1;

repeat

i:=i+1;

x:=x*i

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

repeat



until false;

Оператор repeat until является достаточно непоследовательным с точки зрения семантики английского языка и логики языка PASCAL. Его использование вызывает много ошибок у пользователей в англоязычных странах. Гораздо более последователен синтаксис языка Java, где в качестве цикла с постусловием используется конструкция do{…}while(…).


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

2.10.1. Правила совместимости и автоматического преобразования типов

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

Пример а):

var a,b,c:integer;

переменные a, b, c имеют тождественные типы.

Пример б):

var a1,a2:tA1;

a3:tA1;

Переменные a1, a2, a3 имеют тождественные типы.

Пример в):

type t1=real;

t2=real;

var a:real;

b:t1;

c:t2;

Переменные a, b, c имеют тождественные типы, так как все они приводимы к типу real.

Совместимые по присваиванию (за исключением множеств, указателей, файловых типов и структурных типов, имеющих компоненты файловых типов):

если var a1:tT1;

a2:tT2;

то присваивание a1:=a2 возможно, если
  1. tT1 и tT2 тождественны;
  2. tT2 — подтип tT1, либо оба — подтипы другого типа (в том числе пользовательского) с диапазоном значений tT1, перекрывающим диапазон tT2 . Например, ShortInt – это подтип Integer; byte – также подтип Integer, и одновременно подтип Word, и так далее. Другой пример – тип – диапазон: type t= -50..20 является подтипом ShortInt и т.п.
  3. tT2 — вещественный тип, значения которого попадают в диапазон вещественного типа tT1;
  4. tT2 — целый тип, tT1 — вещественный;
  5. tT2 и tT1 —строковые (любой длины);
  6. tT1 — строковый, tT2 — литерный (т.е. char).


2.10.2. Пользовательские типы. Массивы. Строковые типы.

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

program Prog3;

type

tA1=array[1..100] of integer;

tA2=array[10..20] of real;

tA3=array[1..10] of char;

tA4=array[1..10,1..20] of real;

tA5=array[-10..5] of tA3;

var aA1a,aA1b:tA1;

aA2:tA2;

aA3:tA3;

i:integer;

ch:char;

r:real;

begin

for i:=1 to 100 do aA1a[i]:=i*i;

for i:=1 to 100 do aA1b[i]:=aA1a[i]*2+1;

...

for i:=1 to 20 do aA2[i]:=sin(i);

i:=...;

...;

ch:=...;

r:=aA1[i]/aA2[i-3]+sqrt(i);

aA3[1]:='a';

...;

aA3[i]:=ch;

ch:=aA3[i+1];

...

end.

В других языках:

С,C++:

int A1[100];

A1[0]=5;A1[99]=14;

int A2[10][20];

Java:

int[]A1;

A1=new int[100];

В TP и Delphi имеется предопределенный тип

type string=array[1..255] of char;

а также его подтипы string[n], где n может меняться от 1 до 255.

Описание

var s:string[10];

практически эквивалентно

var s:array[1..10] of char;

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

program MyArray;

var a:array [1..10] of real;

f:text;

i:integer;

begin

assign File(f,'dat.txt');

randomize;

rewrite(f);

for i:=1 to 10 do

begin

a[i]:=random;

writeln(f,a[i]:8:4);

end;

close File(f);

writeln;

writeln('Press to read file')

readln;

reset(f);

for i:=1 to 10 do

begin

readln(f,a[i]);

writeln(a[i]:8:4)

end;

close File(f);

readln

end.

Объяснение операций работы с файлами будет дано позже.


2.10.3. Перечисления

type имя типа = (идентификатор1, идентификатор2,…, идентификаторN);

Примеры:

month = (Jan,Feb,March,Apr,May,June,Jul,Aug,Sept,Oct,Nov,Dec);

type t1 = (x1,x2,x3);

var ab:t1;

m:month;

begin

case m of

Dec,Jan,Feb: operator1;

March..May: operator2

else operator2;

a:=x2;{ord(a)gacm1}

b:=x3;{ord(b)gacm2}

……

a:=t1(0);{явное приведение типа – обратно к функции ord}

В других языках:

C++:

enum Month carrentMonth;

if (carrentmonth!=Jan){…}

Но:

Jan==0,Feb==1,…;

Можно даже

Enum Month{Jan=1,Feb,…,Dec=14};


2.10.4. Множества

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

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

Формат задания типа “множество”:

type

Имя_типа1=set of (порядковый_тип);

Имя_типа2=set of значение1..значение2;

Пример:

type

My=set of char;

MyInterval=set of 1..10;

MyEnumeration=set of (Jan,Feb,…);

var

aSet1: MyChars;

aSet2: MyInterval;

const

aLetter:set of myChars=[‘I’,’k’,’l’,’z’];{Определение

множества без предварительного описания в разделе типов}

begin

aSet1:=[‘a’,’b’,’z’];

……

aSet1:=[ ];

end

В данном примере переменная aSet1 и статическая переменная aLetter могут принимать любые значения , aSet2 — любое значение в диапазоне 1..10; . Попытка присвоить другие значения вызовет ошибку времени исполнения.

В выражениях на языке Паскаль (т.е. в разделах реализации процедур, функций или в теле программы) значения множеств указываются в квадратных скобках: [1,2,3,4], ['a','b','c'], ['a'..'z']. Если множество не имеет элементов, оно называется пустым и обозначается как [].