Перечисляемый тип данных c. Простые типы данных

Перечисляемый тип данных c. Простые типы данных

{косвенная рекурсия

{раздел выполнения основной программы} PR_2

Здесь процедура Pr_1 при первом вызове инициирует случайное трехзначное число "n1" - выигрышный номер. При каждом вызове процедура Pr_1 запрашивает ввод трехзначного номера билета "n". Если номер билета не совпал (n<>n1) и остались еще билеты (i<>0), то снова вызывается процедура Pr_1, иначе вызывается процедура Pr_2 (окончание рекурсивного вызова). Если номера совпали (n1=n), то выводится сообщение: "Вы угадали, получите выигрыш в банке!". Процедура Pr_2 либо вызывает процедуру Pr_1, либо программа заканчивается (оператор Halt). В процедуре Pr_2 заголовок не имеет параметров, а в процедуре Pr_1 параметры указываются при первом описании. В данном случае приводится управляемая на каждом шаге рекурсия (процедура запрашивает номер билета). Включив тело процедуры Pr_2 в Pr_1 и введя операторы цикла, нетрудно избавиться от рекурсивного вызова процедур.

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

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

В Турбо Паскале пять структуированных типов:

массивы;

строки;

множества;

записи;

файлы;

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

Перечисляемый тип данных

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

перечисляемый тип, заключается в круглые скобки.

Программист объединяет в одну группу в соответствии с каким-либо признаком всю совокупность значений, составляющих перечисляемый тип. Например, перечисляемый тип Rainbow (РАДУГА) объединяет скалярные значе-

ния RED, ORANGE, YELLOW, GREEN, LIGHT_BLUE, BLUE, VIOLET (КРАСНЫЙ, ОРАНЖЕВЫЙ, ЖЕЛТЫЙ, ЗЕЛЕНЫЙ, ГОЛУБОЙ, СИНИЙ, ФИОЛЕТОВЫЙ). Перечисляемый тип Traffic_Light (СВЕТОФОР) объединяет скалярные значения RED, YELLOW, GREEN (КРАСНЫЙ, ЖЕЛТЫЙ, ЗЕЛЕНЫЙ).

Перечисляемый тип описывается в разделе описания типов, например: Type

Rainbow = (RED, ORANGE, YELLOW,

GREEN, LIGHT_BLUE, BLUE, VIOLET);

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

Описание переменных, принадлежащих к скалярным типам, которые объявлены в разделе описания типов, производится с помощью имен типов.

Например:

type Traffic_Light= (RED, YELLOW, GREEN); var Section: Traffic_Light;

Это означает, что переменная Section может принимать значения RED, YELLOW или GREEN.

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

var Section: (RED, YELLOW, GREEN);

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

К переменным перечисляемого типа может быть применим оператор присваивания:

Section:= YELLOW;

Упорядоченная последовательность значений, составляющих перечисляемый тип, автоматически нумеруется, начиная с нуля и далее через единицу. Отсюда следует, что к перечисляемым переменным и константам могут быть применены операции отношения и стандартные функции Pred, Succ, Ord.

Интервальный тип данных

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

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

Примеры отрезков: 1..10 -15..25

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

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

Массивы

Массивы – это совокупности однотипных элементов. Характеризуются они следующим:

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

число компонент массива определяется при его описании и в дальнейшем не меняется.

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

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

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

имя типа = array[ список индексов ] of тип

Здесь имя типа – правильный идентификатор; список индексов - список одного или нескольких индексных типов, разделенных запятыми; тип - любой тип данных.

Вводить и выводить массивы можно только поэлементно.

Пример 1. Ввод и вывод одномерного массива. const

mas = array of integer;

a: mas; i: byte;

writeln("введите элементы массива"); for i:=1 to n do readln(a[i]); writeln("вывод элементов массива:");

for i:=1 to n do write(a[i]:5); end.

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

var a,b,c: array of integer;

Если массивы a и b описаны как: var

a = array of integer;

b = array of integer;

то переменные a и b считаются разных типов. Для обеспечения совместимости применяйте описание переменных через предварительное описание типа.

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

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

Например: type

mas = array of array of integer;

Такую запись можно заменить более компактной: type

mas = array of integer;

Таким образом возникает понятие многомерного массива. Глубина вложенности массивов произвольная, поэтому количество элементов в списке индексных типов (размерность массива) не ограничена, однако не может быть более 65520 байт.

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

for i:=1 to m do

for j:=1 to n do a:=random(10);

Для "красивого" вывода матрицы на экран используйте такой цикл: for i:=1 to m do begin

for j:=1 to n do write(a:5); writeln;

Пример. Найти длину n-мерного вектора a (n <= 50): x = (a12+a22+...+an2)

const maxSize = 50;

x: double; i, n: byte;

write(‘n = ’) ; read (n) ;

{ вычисление суммы }

x := 0 ;

for i:= 1 to n do

x := x + sqr (a [i]) ;

{ вычисление длины вектора }

x := sqrt (x) ;

write (‘длина вектора a =‘, x: 8:2) ;

Пример. Найти количество положительных, отрицательных и нулевых элементов массива a (количество элементов <= 50).

const maxSize = 50;

type vector = array of double; var a: vector;

i, n, kplus, kminus, kzero: byte;

write(‘n = ’) ; read (n) ;

{ ввод массива } for i:= 1 to n do

write (‘a[‘, i, ‘]=‘) ; read (a[i]) ;

{ инициализация счетчиков } kplus:= 0 ; kminus:= 0 ; kzero:= 0 ; for i:= 1 to n do

then inc (kminus) else if a [i] > 0

then inc (kplus) else inc (kzero) ;

write (‘k+ =‘, kplus , ‘ k- =‘, kminus, ‘ k0 =‘, kzero) ;

Пример. Проверить, является ли числовой массив a упорядоченным по возрастанию (количество элементов <= 50).

const maxSize = 50;

type vector = array of double; var a: vector;

write(‘n = ’) ; read (n) ;

{ ввод массива } for i:= 1 to n do begin

write (‘a[‘, i, ‘]=‘) ; read (a[i]) ;

p:= 0 ; { установка флажка} for i:= 1 to n - 1 do

if a <= a [i] then p:= 1;

{ если нарушилось возрастание, то смена флажка } if p = 1

then write (‘нет’) else write (‘да’) ;

Нахождение максимального элемента массива - подход к алгоритму. n = 1 тогда nMax:= 1 ;

n = 2 тогда nMax:= 1 ;

if a > a then nMax:= 2 ;

n = 3 тогда …… if a > a then nMax:= 3 ;

Пример. Найти значение и номер максимального элемента числового массива a (количество элементов <= 50).

const maxSize = 50;

type vector = array of double; var a: vector;

i, n, nMax: byte;

write(‘n = ’) ; read (n) ;

write (‘a[‘, i, ‘]=‘) ; read (a[i]) ;

for i:= 1 to n do

if a [i] > a then nMax:= i;

{ если встретился больший элемент, то запомнили его номер }

write (‘номер =’, nMax , ‘ max значение =‘, a :8: 2) ;

Сортировка числового массива - подход к алгоритму пузырьковой сортировки.

Для определенности - по возрастанию:

n = 2 тогда if a < a

then { если элементы стоят неправильно, то меняем их местами} begin t:= a ;

a := a ; a := t ; end;

n = 3 тогда if a < a

then begin t:= a ; a := a ;

then begin t:= a ; a := a ;

{ максимальный элемент на месте}

Пример. Упорядочить по возрастанию числовой массив a (количество элементов <= 50).

const maxSize = 50;

type vector = array of double; var a, b: vector;

i, n, k: byte; t: double;

write(‘n = ’) ; read (n) ;

{ ввод массива } for i:= 1 to n do begin

write (‘a[‘, i, ‘]=‘) ; read (a[i]) ;

b:= a ; { присваивание массива} for k:= 1 to n-1 do

for i:= 1 to n - k do if b < b[i]

then begin t:= b[i] ;

b [i] := b ; b := t ;

end; writeln (‘упорядоченный массив:’) ; for i:= 1 to n do

writeln (‘b[‘, i, ‘]=‘, b[i] :8:2) ;

Пример. Найти сумму элементов матрицы a, состоящей из n строк и m

столбцов (n <= 5, m <= 4). uses wincrt;

const RSize = 5; CSize = 4;

sum: double; i, j, n, m: byte;

{ ввод массива } for i:= 1 to n do

for j:= 1 to m do begin

{ вычисление суммы }

for i:= 1 to n do

for j:= 1 to m do sum:= sum + a ;

write (‘сумма =‘, sum: 8:2) ;

Пример. Найти количество нулевых элементов в каждом столбце массива a. uses wincrt;

const RSize = 5; CSize = 4;

type matr = array of double; var a: matr;

i, j, n, m, kzero: byte;

for i:= 1 to n do

for j:= 1 to m do begin

write (‘a[‘, i, ‘,’, j, ‘]=‘) ; read (a) ;

for j:= 1 to m do{ цикл по столбцам } begin

{ инициализация счетчика } kzero:= 0 ;

for i:= 1 to n do if a [i] = 0

then inc (kzero) ;

writeln (j, ‘-й столбец:k0 =‘, kzero) ;

Пример. Найти номера строк массива a, в которых есть хоть один 0. uses wincrt;

const RSize = 5; CSize = 4;

type matr = array of double; var a: matr;

i, j, n, m, p: byte;

write(‘n = ’) ; read (n) ; write(‘m = ’) ; read (m) ; { ввод массива }

for i:= 1 to n do

for j:= 1 to m do begin

write (‘a[‘, i, ‘,’, j, ‘]=‘) ; read (a) ;

end ; for i:= 1 to n do

p:= 0 ; { установка флажка} for j:= 1 to m do

then p:= 1;{смена флажка } if p = 1

then writeln (‘номер строки=’, i);

Пример. Найти значение и номера максимального элемента числового массива a

const RSize = 5; CSize = 4;

type matr = array of double; var a: matr;

i, j, n, m, Rmax, Cmax: byte;

write(‘n = ’) ; read (n) ; write(‘m = ’) ; read (m) ; { ввод массива }

for i:= 1 to n do

for j:= 1 to m do begin

write (‘a[‘, i, ‘,’, j, ‘]=‘) ; read (a) ;

end ; Rmax:=1 ; Cmax:= 1 ; for i:= 1 to n do

for j:= 1 to m do

if a > a then

Rmax:= i; Cmax:= j ; end;

write (‘max = a[‘ , Rmax, ‘,’ , Cmax,‘ ]= ‘ , a :8: 2)

Пример. Переставить строки матрицы a в порядке возрастания элементов первого столбца.

const RSize = 5; CSize = 4;

type matr = array of double; var a , b: matr;

i, j, k, n, m: byte; t: double;

write(‘n = ’) ; read (n) ; write(‘m = ’) ; read (m) ; { ввод массива }

for i:= 1 to n do

for j:= 1 to m do begin

write (‘a[‘, i, ‘,’, j, ‘]=‘) ; read (a) ;

for k:= 1 to n-1 do

for i:= 1 to n - k do

if b < b

then { перестановка строк } for j:= 1 to m do

b := b ; b := t ; end;

writeln (‘упорядоченный массив:’) ; for i:= 1 to n do

for j:= 1 to m do

write (b :8:2) ;

writeln; { переход к новой строке }

Пример. Выполнить умножение матрицы a на вектор x. uses wincrt;

const RSize = 5; CSize = 4; VSize = 5 ;

type matr = array of double; vector = array of double;

i, j, k, n, m: byte;

write(‘n = ’) ; read (n) ; write(‘m = ’) ; read (m) ;

{ ввод матрицы } for i:= 1 to n do

for j:= 1 to m do begin

write (‘a[‘, i, ‘,’, j, ‘]=‘) ; read (a) ;

{ ввод вектора }

for j:= 1 to m do begin

write (‘x[‘, j, ‘]=‘) ; read (x[j]) ;

for i:= 1 to n do begin

for j:= 1 to m do

y[ i ] := y[ i ] + a * x[j] ;

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

for i:= 1 to n do

writeln (‘y[‘, i, ‘]=‘, y[i] :8:2) ;

Пример. Выполнить умножение матрицы a на матрицу b. uses wincrt;

const RSize = 5; CSize = 5;

type matr = array of double; var a, b, c: matr;

i, j, k, n, m, L: byte;

write(‘n = ’) ; read (n) ; write(‘m = ’) ; read (m) ; { ввод матрицы a} for i:= 1 to n do

for j:= 1 to m do begin

write (‘a[‘, i, ‘,’, j, ‘]=‘) ; read (a) ;

end ; write(‘L = ’) ; read (L) ;

{ ввод матрицы b} for i:= 1 to m do

for j:= 1 to L do begin

write (‘b[‘, i, ‘,’, j, ‘]=‘) ; read (b) ;

{ количество строк матрицы b равно количеству столбцов матрицы a} for i:= 1 to n do

for j:= 1 to L do begin

c[ i , j] := 0 ;

for k:= 1 to m do

c[ i , j] := c[ i , j] + a * b ;

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

for i:= 1 to n do begin

for j:= 1 to L do

write (c :8:2) ; writeln;

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

Описание и использование

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

type Cardsuit = (clubs, diamonds, hearts, spades);

Здесь производится объявление типа данных Cardsuit (карточная масть), значениями которого может быть любая из четырёх перечисленных констант. Переменная типа Cardsuit может принимать одно из значений clubs, diamonds, hearts, spades , допускается сравнение значений типа перечисление на равенство или неравенство, а также использование их в операторах выбора (в Паскале - case) в качестве значений, идентифицирующих варианты.

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

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

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

Реализация

Обычно в процессе компиляции значения перечислений представляются при помощи целых чисел. В зависимости от конкретного языка программирования такое представление может быть либо полностью скрыто от программиста, либо доступно ему с помощью тех или иных «обходных манёвров» (например, принудительного преобразования значения типа перечисление к значению типа «целое число»), либо даже управляемо программистом (в таких случаях программист имеет возможность явно указать, какими числами будут кодироваться все или некоторые значения типа-перечисления). У всех вариантов есть свои положительные и отрицательные стороны. С одной стороны, возможность использования числовых значений констант, составляющих тип-перечисление, особенно при злоупотреблении ею, лишает смысла использование этих типов и создаёт опасность появления ошибок (когда используются числовые значения, для которых в типе нет соответствующих констант). С другой стороны, явное управление значениями даёт некоторые дополнительные возможности. Например, позволяет использовать типы-перечисления при организации интерфейса с модулями, написанными на других языках, если они используют или возвращают кодированные целыми числами значения из некоторого предопределённого набора.

Ещё одна возможность, которую дают перечислимые типы на уровне реализации языка - экономия памяти. При небольшом объёме типа-перечисления для хранения значения этого типа достаточно нескольких битов (вышеприведённый тип Cardsuit требует всего два бита на значение, в то время как стандартное целое число на большинстве используемых архитектур занимает 32 бита - в 16 раз больше), и компилятор может использовать этот факт для уплотнения хранения данных в памяти. Это может быть особенно важно, если несколько значений типов-перечислений хранятся в одной записи - уплотнение записей при обработке больших их количеств может освободить много памяти. Правда, необходимо отметить, что компиляторы обычно не реализуют эту возможность, по крайней мере, в последнее время, когда компьютерная память существенно подешевела.

Критика

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

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

Описание перечислений в различных языках

Ada

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

type Cardsuit is (clubs, diamonds, hearts, spades);

и языки с C-подобным синтаксисом

enum cardsuit { CLUBS, DIAMONDS, HEARTS, SPADES };

Динамические языки слабой типизации с C-подобным синтаксисом (например perl или JavaScript), как правило, не имеют перечислений.

C++

Перечисления в языке C++ прямо наследуют поведение перечислений языка C, за исключением того, что перечисляемый тип в C++ - настоящий тип, и ключевое слово enum используется только при объявлении такого типа. Если при обработке параметра являющегося перечислением, какое-либо значение из перечисления не обрабатывается (например один из элементов перечисления забыли обработать в конструкции switch), то компилятор может выдать предупреждение о забытом значении.

Java

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

enum Cardsuit { Clubs, Diamonds, Spades, Hearts }

Haskell

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

Data Bool = False | True

Напишите отзыв о статье "Перечисляемый тип"

Примечания

Отрывок, характеризующий Перечисляемый тип

– Поручите это мне, – сказала княжна Марья. – Я знаю…
Пьер смотрел в глаза княжне Марье.
– Ну, ну… – говорил он.
– Я знаю, что она любит… полюбит вас, – поправилась княжна Марья.
Не успела она сказать эти слова, как Пьер вскочил и с испуганным лицом схватил за руку княжну Марью.
– Отчего вы думаете? Вы думаете, что я могу надеяться? Вы думаете?!
– Да, думаю, – улыбаясь, сказала княжна Марья. – Напишите родителям. И поручите мне. Я скажу ей, когда будет можно. Я желаю этого. И сердце мое чувствует, что это будет.
– Нет, это не может быть! Как я счастлив! Но это не может быть… Как я счастлив! Нет, не может быть! – говорил Пьер, целуя руки княжны Марьи.
– Вы поезжайте в Петербург; это лучше. А я напишу вам, – сказала она.
– В Петербург? Ехать? Хорошо, да, ехать. Но завтра я могу приехать к вам?
На другой день Пьер приехал проститься. Наташа была менее оживлена, чем в прежние дни; но в этот день, иногда взглянув ей в глаза, Пьер чувствовал, что он исчезает, что ни его, ни ее нет больше, а есть одно чувство счастья. «Неужели? Нет, не может быть», – говорил он себе при каждом ее взгляде, жесте, слове, наполнявших его душу радостью.
Когда он, прощаясь с нею, взял ее тонкую, худую руку, он невольно несколько дольше удержал ее в своей.
«Неужели эта рука, это лицо, эти глаза, все это чуждое мне сокровище женской прелести, неужели это все будет вечно мое, привычное, такое же, каким я сам для себя? Нет, это невозможно!..»
– Прощайте, граф, – сказала она ему громко. – Я очень буду ждать вас, – прибавила она шепотом.
И эти простые слова, взгляд и выражение лица, сопровождавшие их, в продолжение двух месяцев составляли предмет неистощимых воспоминаний, объяснений и счастливых мечтаний Пьера. «Я очень буду ждать вас… Да, да, как она сказала? Да, я очень буду ждать вас. Ах, как я счастлив! Что ж это такое, как я счастлив!» – говорил себе Пьер.

В душе Пьера теперь не происходило ничего подобного тому, что происходило в ней в подобных же обстоятельствах во время его сватовства с Элен.
Он не повторял, как тогда, с болезненным стыдом слов, сказанных им, не говорил себе: «Ах, зачем я не сказал этого, и зачем, зачем я сказал тогда „je vous aime“?» [я люблю вас] Теперь, напротив, каждое слово ее, свое он повторял в своем воображении со всеми подробностями лица, улыбки и ничего не хотел ни убавить, ни прибавить: хотел только повторять. Сомнений в том, хорошо ли, или дурно то, что он предпринял, – теперь не было и тени. Одно только страшное сомнение иногда приходило ему в голову. Не во сне ли все это? Не ошиблась ли княжна Марья? Не слишком ли я горд и самонадеян? Я верю; а вдруг, что и должно случиться, княжна Марья скажет ей, а она улыбнется и ответит: «Как странно! Он, верно, ошибся. Разве он не знает, что он человек, просто человек, а я?.. Я совсем другое, высшее».
Только это сомнение часто приходило Пьеру. Планов он тоже не делал теперь никаких. Ему казалось так невероятно предстоящее счастье, что стоило этому совершиться, и уж дальше ничего не могло быть. Все кончалось.
Радостное, неожиданное сумасшествие, к которому Пьер считал себя неспособным, овладело им. Весь смысл жизни, не для него одного, но для всего мира, казался ему заключающимся только в его любви и в возможности ее любви к нему. Иногда все люди казались ему занятыми только одним – его будущим счастьем. Ему казалось иногда, что все они радуются так же, как и он сам, и только стараются скрыть эту радость, притворяясь занятыми другими интересами. В каждом слове и движении он видел намеки на свое счастие. Он часто удивлял людей, встречавшихся с ним, своими значительными, выражавшими тайное согласие, счастливыми взглядами и улыбками. Но когда он понимал, что люди могли не знать про его счастье, он от всей души жалел их и испытывал желание как нибудь объяснить им, что все то, чем они заняты, есть совершенный вздор и пустяки, не стоящие внимания.
Когда ему предлагали служить или когда обсуждали какие нибудь общие, государственные дела и войну, предполагая, что от такого или такого исхода такого то события зависит счастие всех людей, он слушал с кроткой соболезнующею улыбкой и удивлял говоривших с ним людей своими странными замечаниями. Но как те люди, которые казались Пьеру понимающими настоящий смысл жизни, то есть его чувство, так и те несчастные, которые, очевидно, не понимали этого, – все люди в этот период времени представлялись ему в таком ярком свете сиявшего в нем чувства, что без малейшего усилия, он сразу, встречаясь с каким бы то ни было человеком, видел в нем все, что было хорошего и достойного любви.
Рассматривая дела и бумаги своей покойной жены, он к ее памяти не испытывал никакого чувства, кроме жалости в том, что она не знала того счастья, которое он знал теперь. Князь Василий, особенно гордый теперь получением нового места и звезды, представлялся ему трогательным, добрым и жалким стариком.
Пьер часто потом вспоминал это время счастливого безумия. Все суждения, которые он составил себе о людях и обстоятельствах за этот период времени, остались для него навсегда верными. Он не только не отрекался впоследствии от этих взглядов на людей и вещи, но, напротив, в внутренних сомнениях и противуречиях прибегал к тому взгляду, который он имел в это время безумия, и взгляд этот всегда оказывался верен.
«Может быть, – думал он, – я и казался тогда странен и смешон; но я тогда не был так безумен, как казалось. Напротив, я был тогда умнее и проницательнее, чем когда либо, и понимал все, что стоит понимать в жизни, потому что… я был счастлив».
Безумие Пьера состояло в том, что он не дожидался, как прежде, личных причин, которые он называл достоинствами людей, для того чтобы любить их, а любовь переполняла его сердце, и он, беспричинно любя людей, находил несомненные причины, за которые стоило любить их.

С первого того вечера, когда Наташа, после отъезда Пьера, с радостно насмешливой улыбкой сказала княжне Марье, что он точно, ну точно из бани, и сюртучок, и стриженый, с этой минуты что то скрытое и самой ей неизвестное, но непреодолимое проснулось в душе Наташи.
Все: лицо, походка, взгляд, голос – все вдруг изменилось в ней. Неожиданные для нее самой – сила жизни, надежды на счастье всплыли наружу и требовали удовлетворения. С первого вечера Наташа как будто забыла все то, что с ней было. Она с тех пор ни разу не пожаловалась на свое положение, ни одного слова не сказала о прошедшем и не боялась уже делать веселые планы на будущее. Она мало говорила о Пьере, но когда княжна Марья упоминала о нем, давно потухший блеск зажигался в ее глазах и губы морщились странной улыбкой.
Перемена, происшедшая в Наташе, сначала удивила княжну Марью; но когда она поняла ее значение, то перемена эта огорчила ее. «Неужели она так мало любила брата, что так скоро могла забыть его», – думала княжна Марья, когда она одна обдумывала происшедшую перемену. Но когда она была с Наташей, то не сердилась на нее и не упрекала ее. Проснувшаяся сила жизни, охватившая Наташу, была, очевидно, так неудержима, так неожиданна для нее самой, что княжна Марья в присутствии Наташи чувствовала, что она не имела права упрекать ее даже в душе своей.
Наташа с такой полнотой и искренностью вся отдалась новому чувству, что и не пыталась скрывать, что ей было теперь не горестно, а радостно и весело.
Когда, после ночного объяснения с Пьером, княжна Марья вернулась в свою комнату, Наташа встретила ее на пороге.
– Он сказал? Да? Он сказал? – повторила она. И радостное и вместе жалкое, просящее прощения за свою радость, выражение остановилось на лице Наташи.
– Я хотела слушать у двери; но я знала, что ты скажешь мне.
Как ни понятен, как ни трогателен был для княжны Марьи тот взгляд, которым смотрела на нее Наташа; как ни жалко ей было видеть ее волнение; но слова Наташи в первую минуту оскорбили княжну Марью. Она вспомнила о брате, о его любви.

На занятии будет объяснен алгоритм создания типов данных пользователя в Паскаль (Type). Будут разобраны примеры.

Типы данных в Pascal делятся на простые и сложные.

К простым типам относятся стандартные, перечисляемые и ограниченные.

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

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

Новые (пользовательские) типы данных нужны в первую очередь для наглядности и удобства:

Пример: Задана матрица размерностью 10 x 50. Выполнить описание матрицы, используя пользовательский тип данных

procedure p(a: array of Integer);

Зато следует создать тип данных и записать так:

1 2 type vector = array [ 1 .. 10 ] of integer ; var procedure p(a: vector) ;

type vector = array of integer; var procedure p(a: vector);

Примеры описания массивов при помощи новых типов

type vector = array of integer; matritsa = array of vector;

  • 1 type matritsa = array [ 1 .. 8 ] of array [ 1 .. 10 ] of integer ;

    type matritsa = array of array of integer;

  • 1 type matritsa = array [ 1 .. 8 , 1 .. 10 ] of integer ;

    type matritsa = array of integer;

  • В следующем примере переменные c и d описаны одинаково:

    1 2 3 4 5 6 type vector = array [ 1 .. 10 ] of integer ; matritsa = array [ 1 .. 8 ] of vector; var a, b: vector; c: matritsa; d: array [ 1 .. 8 ] of vector;

    type vector = array of integer; matritsa = array of vector; var a,b: vector; c:matritsa; d:array of vector;

    Type 1 : Заданы массивы а, b и c. Найти среднее арифметическое минимальных элементов массива (использовать формирования массива и ).
    При описании процедур использовать пользовательские типы данных

    Перечисляемый тип и интервальный тип в Паскаль

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

    В программе можно использовать переменные такого типа, который не совпадает ни с одним из стандартных типов.

    Так, тип может задаваться перечислением значений при объявлении; переменная данного типа может принимать любое из этих значений.

    Эти значения не могут являться строками, их нельзя вывести на печать и нельзя ввести в компьютер при помощи операторов Read и Write .

    Рассмотрим пример создания перечисляемого типа в Паскаль:

    type pt= (word1, word2, ... wordN ) ; var w: pt;

    type pt=(word1,word2, ... wordN); var w: pt;

  • pt – идентификатор типа (произвольный),
  • word1 , word2 … — конкретные значения, которые может принимать переменная w , принадлежащая типу pt
  • значения данного типа считаются упорядоченными, т.е. описание типа одновременно вводит упорядочение word1 .
  • Интервальный тип

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

    Рассмотрим пример объявления интервального типа:

    a: min.. max ;
  • a – интервальная переменная
  • min – нижняя граница
  • max – верхняя граница подмножества
  • границы диапазона разделяются двумя точками
  • граница min всегда должна быть меньше max
  • константы min и max должны принадлежать одному и тому же типу. Они определяют базовый тип переменной a .
  • Совместное использование перечисляемого и интервального типов

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

    Пример: Если переменная b может принимать одно из значений red , yellow , green , то эту переменную можно описать так: b: red..green; базовым типом для b является тип color :

    type color= (red, yellow, green, blue) ; var b: red.. green ; begin b: = red; writeln (b) ; b: = yellow; writeln (b) ; b: = green; writeln (b) ; readln end .

    type color=(red,yellow,green,blue); var b:red..green; begin b:=red; writeln(b); b:=yellow; writeln(b); b:=green; writeln(b); readln end.

    В данном примере тип color — является базовым. Переменная b интервального типа определена при помощи базового перечисляемого типа.

    Пример: Известно, сколько дней в каждом месяце года. Сколько дней летом?
    31,28,31,30,31,30,31,31,30,31,30,31

    Один из вариантов решения данной задачи выглядит так:

      Показать решение:

      1 2 3 4 5 6 7 8 const dni: array [ 1 .. 12 ] of byte = (31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 ) ; var s, i: integer ; begin s: = 0 ; for i: = 6 to 8 do s: = s+ dni[ i] ; {летние месяцы - 6, 7, 8} writeln (s) end .

      const dni: array of byte = (31,28,31,30,31,30,31,31,30,31,30,31); var s,i: integer; begin s:=0; for i:=6 to 8 do s:=s+dni[i]; {летние месяцы - 6, 7, 8} writeln(s) end.

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

      Показать решение:

      1 2 3 4 5 6 7 8 9 TYPE mes = (january, february, march, april, may, june, july, august, september, october, november, december) ; CONST dni: array [ january.. december ] of Byte = (31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 ) ; VAR s: Integer ; i: mes; {переменная счетчика цикла i задана типом mes, а не Integer} BEGIN s: = 0 ; for i: = june to august do s: = s+ dni[ i] ; WriteLn (s) END .

      TYPE mes = (january, february, march, april, may, june, july, august, september, october, november, december); CONST dni:array of Byte = (31,28,31,30,31,30,31,31,30,31,30,31); VAR s:Integer; i:mes; {переменная счетчика цикла i задана типом mes, а не Integer} BEGIN s:=0; for i:=june to august do s:=s+dni[i]; WriteLn(s) END.

    Type 2: Определить по названию дня недели выходной ли это или рабочий день.

  • Определить перечислимый тип со значениями дней недели (mon , tue , wed , thu , fri , sat , sun ).
  • В программе присвоить значение переменной (из значений типа, например, mon ).
  • Проверять переменную: если значение суббота или воскресенье – выдавать сообщение «Выходной!» , иначе «Работаем!» .
  • Type 3: В зависимости от месяца года, выдавать сообщение «холодно» — если зимний месяц, и «тепло» — если летний.

  • Определить перечисляемый тип со значениями названий месяцев года.
  • Объявить переменную, относящуюся к этому типу.
  • В программе присвоить значение переменной (из значений типа).
  • Проверять переменную: если значение относится к зимнему месяцу, — выдавать сообщение «холодно» иначе, — «тепло» .
  • Реализовать несколькими способами.
  • Writeln (pribitie) end .

    var otpravlenie,pribitie:byte; begin otpravlenie:=22; pribitie:=otpravlenie+10; writeln(pribitie) end.

    программа вместо ответа «8» напечатает ответ «32».
    Введение ограниченного диапазонного типа позволит избежать неправильного результата, однако компилятор все равно выдаст ошибку:

    1 2 3 4 5 6 var otpravlenie, pribitie: 0 .. 24 ; begin otpravlenie: = 22 ; pribitie: = otpravlenie+ 10 ; writeln (pribitiedeva) ; var a: znak; begin a: = lev; if a<= strelets then writeln ("огонь" ) ; if (a>= vesi) and (a<= bliznetsi) then writeln ("воздух" ) ; if (a>= rak) and (a<= ribi) then writeln ("вода" ) ; if (a>= kozerog) and (a<= deva) then writeln ("земля" ) ; end .

    type znak=(oven,lev,strelets,vesi,vodoley, bliznetsi,rak,skorpion,ribi,kozerog,telets,deva); var a:znak; begin a:=lev; if a<=strelets then writeln("огонь"); if (a>=vesi) and (a<=bliznetsi) then writeln ("воздух"); if (a>=rak) and (a<=ribi) then writeln ("вода"); if (a>=kozerog) and (a<=deva) then writeln ("земля"); end.

    Type 5: В зависимости от названия цветка, выдавать к какому сезону года он относится:

  • Весна: подснежник, ирис, нарциссы
  • Лето: ромашка, одуван, мак
  • Осень: астра, хризантема, флокс
  • В языке Паскаль переменные характеризуются своим типом . Тип - это свойство переменой, по которому переменная может принимать множество значений, допустимых этим типом, и участвовать во множестве операций, допустимых над данным типом.

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

    Например:

    n:integer;

    Паскаль - статический язык, из этого следует, что тип переменой определяется при ее описании и не может быть изменен. Язык Паскаль имеет развитую систему видов - все данные должны принадлежать заранее известному типу данных (либо стандартному типу, созданному при разработке языка или пользовательскому типу, который определяет программист). Программист может создавать свои типы произвольной структурой сложности на основе стандартных типов, либо уже определенных пользователем типов. Количество создаваемых типов неограниченно. Пользовательские типы в программе объявляется в разделе TYPE по формату:

    [имя] = [тип]

    Система стандартных типов имеет разветвленную, иерархическую структуру.

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

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

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

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

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

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

    При использовании целочисленных чисел следует руководствоваться вложенностью типов, т.е. типы с меньшим диапазоном могут быть вложены в типы с большим диапазоном. Тип Byte может быть вложен во все типы занимающие 2 и 4 байта. В тоже время тип Short Int, занимающий 1 байт не может быть вложен в тип Word, поскольку не имеет отрицательных значений.

    Можно выделить 5 вещественных типов:

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

    2358.8395

    0.23588395*10 4

    0.23588395*E 4

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

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

    Порядковые типы объединяют в себе несколько простых типов. К ним относятся:

    • все целые типы;
    • символьный тип;
    • логический тип;
    • тип-диапазон;
    • перечисляемый тип.

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

    К значениям порядкового типа может быть применена функция ODD(x), которая возвращает порядковый номер аргумента x.

    Функция PRED(x) - возвращает предшествующее значение порядкового типа. PRED(A) = 5.

    Функция SUCC (x) - возвращает следующее значение порядкового типа. SUCC(A) = 5.

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

    Значениям символьного типа является 256 символов из множества допустимых кодовой таблицей используемого компьютера. Начальная область этого множества, то есть диапазон от 0 до 127 соответствует множеству кодов ASCII, куда загружаются символы алфавита, арабских чисел и специальных символов. Символы начальной области всегда присутствуют на клавиатуре ПК. Старшая область называется альтернативной, она содержит символы национальных алфавитов и различные специальные символы, и символы псевдографики, не соответствующие коду ASCII.

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

    C:= ’A’

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

    Имеются два значения булевского типа: Истина (True) и Ложь (False). Переменные данного типа задаются служебным словом BOOLEAN. Значение булевского типа занимают один байт в оперативной памяти. Значениям Истина и Ложь соответствуют числовые значения 1 и 0.

    Тип-диапазон

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

    [минимальное-значение]…[максимальное-значение]

    Тип-диапазон можно задавать в разделе Type, как определенный тип, а можно непосредственно в разделе Var.

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

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

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

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

    Peoples = (men, women);

    Первое значение - 0, второе значение - 1 и т.д.

    Максимальная мощность 65535 значений.

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

    Строковый тип относится к группе структурированных типов и состоит из базового типа Char. Строковый тип не относится к порядковым типам. Он определяет множество символьных цепочек произвольной длины до 255 символов.

    В программе строковый тип объявляется, словом String. Поскольку String является базовым типом, он описан в языке и объявление переменной типа String осуществляется в Var. При объявлении переменной строкового типа за String в квадратных скобках целесообразно указывать длину строки. Для указания используется целое число от 0 до 255.

    Fam: String;

    Указание длины строки позволяет компилятору отвести под данную переменную указанное число байтов в ОЗУ. Если длина строки не указана, то в этом случае компилятор отведет под значение этой переменной максимальное возможное число байт (255).

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

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

    Синтаксис

    type имя = (идентификатор, идентификатор, ..., идентификатор);

    Замечания

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

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

    Перечисляемые типы являются подклассом порядковых типов.

    Пример

    type Suit = (Clubs, Diamonds, Hearts, Spades);

    При таком объявлении Hearts является константой типа Suit.

    Стандартная функция Ord возвращает порядковый номер перечисляемой константы. В этом примере,

    Ord(Clubs) = 0
    Ord(Diamonds) = 1
    Ord(Hearts) = 2

    Ада

    type Day is (Mon, Tue, Wed, Thu, Fri, Sat, Sun);
    type Suit is (Clubs, Diamonds, Hearts, Spades);
    type Color is (White, Red, Yellow, Green, Blue, Brown, Black);
    type Light is (Red, Amber, Green); -- Red и Green перегружены

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

    © 2024 dhmoscow.ru - Компьютер надо изучать