РефератыИнформатика, программированиеИнИнтервальные типы данных. Оператор TYPE. Массивы

Интервальные типы данных. Оператор TYPE. Массивы



С.А. Григорьев


Интервальный тип - это некоторый подтип порядкового типа данных (вспомним, что порядковые типы - это ShortInt, Byte, Integer, Word, LongInt, Char и Boolean). Пусть, например, некоторая переменная в программе может принимать значения от -1 до 99. Мы могли бы описать ее как LongInt или Integer (глупо!), могли бы описать ее как ShortInt, что достаточно разумно. Но можно создать для нее и специальный тип данных, объединяющий только числа от -1 до 99 :


VAR x : -1..99;


Вместо имени одного из стандартных типов мы использовали в описании переменной построенный нами собственный интервальный тип. Таким образом описанная переменная x может принимать только значения -1,0,1,...,99 , в остальном она ничем не отличается от других целых переменных. Ее можно вводить, выводить, использовать в качестве переменной цикла, подставлять в выражения и т.п. Любой интервальный тип есть подтип некоторого стандартного базового типа, в нашем случае - типа ShortInt. Но если бы мы стали использовать интервальный тип -1..200 , то он бы уже был подтипом типа Integer, а 0..200 - подтипом типа Byte. Компилятор Паскаля самостоятельно анализирует интервальные типы и подбирает для них минимальный подходящий базовый тип. Это нужно знать, чтобы определять размер и способ кодировки ваших переменных. Вы можете выполнить оператор


WRITE('переменная x:-1..99 занимает ',SizeOf(x),' байт');


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


В качестве базового типа можно использовать не только арифметические типы, но и типы Char и Boolean (правда, в последнем случае это довольно бессмысленно). Опишем, например, переменную, значением которой могут быть только маленькие латинские буквы :


VAR Letter : 'a'..'z';


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


VAR RusLetter : 'А'..'я';


В общем случае интервальный тип описывается как


константное выражение 1 .. константное выражение 2,


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


TYPE имя типа=описание типа;


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


CONST Tmin=-5;


Tmax=15;


TYPE T_Range_Type=Tmin..Tmax;


VAR t:T_Range_Type;


TYPE T_Range_SubType=Tmin+3..Tmax-5;


VAR t1:T_Range_SubType;


Заметим, что хороший программист всегда дает имена собственным типам, причем старается, чтобы эти имена были осмысленными.


Теперь, зная об интервальных типах, мы можем говорить о массивах. Массив во всех языках программирования - это множество индексированных (пронумерованных) однотипных элементов. В Паскале описание одномерного массива имеет вид:


ARRAY [тип индекса] OF тип элемента


Здесь тип индекса - ShortInt, Byte, Char, Boolean или интервальный тип; тип элемента - любой тип, в том числе и массив. Вы заметили, что не все порядковые типы можно использовать как тип индекса, это не значит, что, например, тип Word чем-то хуже типа Byte. Такое ограничение обусловлено тем, что в Паскале никакой объект не может иметь размер больше (64К - 2) байта, или 65534 байта. Это ограничение действует и для интервальных типов, так вы можете описать массив VAR a : ARRAY[1..65534] OF BYTE;


нонемассив VAR a : ARRAY[1..65535] OF BYTE;


инемассив VAR a : ARRAY[1..33000] OF WORD;


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


VAR a : ARRAY[Char] OF 1..5;


- массив из 256 элементов, каждый из которых есть целое число от 1 до 5, индексы элементов изменяются от #0 до #255;


CONST Max = 99;


Min = 10;


TYPE Nums = Min..Max;


TYPE ArrayType = ARRAY[-10..0] OF Nums;


VAR a : ArrayType;


- массив из 11 элементов с индексами от -10 до 0, каждый элемент - целое положительное число из двух цифр;


TYPE IndexType = 'a'..'z';


VAR a : ARRAY[IndexType] OF BOOLEAN;


- массив из 26 элементов с индексами от 'a' до 'z', каждый элемент - логическая переменная.


В программе вы можете использовать как массивы целиком, так и отдельные элементы массивов. Элемент одномерного массива записывается в виде:


имя массива [ индексное выражение ]


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


VAR a : ARRAY[1..3] OF REAL;


b,c,d : ARRAY[1..3] OF REAL;


TYPE Massiv=ARRAY[1..3] OF REAL;


VAR e,f : Massiv;


g : Massiv;


h,i : Massiv;


то массивы b,c,d - однотипные и массивы e,f,g,h,i тоже однотипные, но массивы a и b (a и c,a и d) имеют разный тип; и массивы b (c,d,a) и e (f,g,h,i) тоже имеют разный тип! Компилятор считает, что две переменные имеют один и тот же тип, только если они описаны в одном операт

оре через запятую, либо имена их типов одинаковы! Запомните это очень важное правило.


Запишем пример программы, использующей (пока одномерные) массивы:


{ программа вводит массив из N целых чисел, где N не превосходит 20, и выводит его в порядке неубывания }


CONST Nmax=20;


TYPE IndexType=1..Nmax;


Massiv=ARRAY[IndexType] OF Integer;


VAR a : Massiv; i,j,N : IndexType; t : Integer;


BEGIN WRITELN;


REPEAT WRITE('Введите длину массива от 1 до ',Nmax,' ');


READ(N); WRITELN;


UNTIL (N>=1)AND(N<=Nmax);


{ Вводим массив поэлементно }


WRITELN('Введите элементы массива');


FOR i:=1 TO N DO READ(a[i]);


{ Сортируем элементы массива по неубыванию. Используем очень простой, но


неэффективный алгоритм сортировки - сравниваем каждый элемент с каждым


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


FOR i:=1 TO N-1 DO FOR j:=i+1 TO N DO


IF a[i]>a[j] THEN BEGIN t:=a[i]; a[i]:=a[j]; a[j]:=t; END;


{ Выводим отсортированный массив поэлементно }


WRITELN('Результат сортировки :');


FOR i:=1 TO N DO WRITE(a[i]:8);


END.


Обратите внимание на алгоритм перестановки двух элементов! Запись a[i]:=a[j]; a[j]:=a[i]; , очевидно, привела бы к неверному результату. Использованный нами алгоритм сортировки вполне надежен, но не очень хорош, так как выполняет много лишних операций. Не составляет труда усовершенствовать его - для каждого i от 1 до N-1 найдем наименьший из элементов ai, ai+1, ... , aN и поместим его на i-е место; такой алгоритм выполняет столько же сравнений, сколько и первоначальный, но требует существенно меньшего количества перестановок.


FOR i:=1 TO N-1 DO BEGIN


a_max:=a[i]; n_max:=i;


FOR j:=i+1 TO N DO


IF a[j]<a_max THEN BEGIN a_max:=a[j]; n_max:=j; END;


IF n_max<>i THEN BEGIN a[n_max]:=a[i]; a[i]:=a_max; END;


END;


Как видите, запись алгоритма несколько длиннее, и потребовалось две новых переменных a_max - типа Integer и n_max - типа IndexType. Это действие универсального закона сохранения - из двух верных алгоритмов лучший, как правило, сложнее.


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


VAR a : ARRAY[1..10] OF ARRAY[1..20] OF Real;


Переменную a можно рассматривать как одномерный массив одномерных массивов и использовать в программе запись вида a[i] ; но можно рассматривать и как двумерный массив вещественных чисел. Элемент этого массива записывается в программе в виде a[ индексное выражение , индексное выражение ] и является переменной типа Real, например, a[i+1,3]. Впрочем, можно записать и так: a[i+1][3], обе эти записи эквивалентны. Описание многомерных массивов также можно записывать компактно: вместо


ARRAY[ t1 ] OF ARRAY[ t2 ] OF ARRAY ... OF t ;


можно записать


ARRAY[ t1 , t2 , ... ] OF t ;


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


CONST Nmax=20; {максимальный размер матрицы}


TYPE IndexType=1..Nmax;


Matrix =ARRAY[IndexType,IndexType] OF Real;


VAR a,b,c : Matrix; n,i,j,k : IndexType;


BEGIN WRITE('введите размер матриц '); READ(n);


IF (n<1)OR(n>Nmax) THEN BEGIN


WRITELN('неверный размер!'); Halt; END;


WRITELN('введите матрицу A построчно ');


FOR i:=1 TO n DO FOR j:=1 TO n DO READ(a[i,j]);


WRITELN('введите матрицу B построчно ');


FOR i:=1 TO n DO FOR j:=1 TO n DO READ(b[i,j]);


FOR i:=1 TO n DO FOR j:=1 TO n DO BEGIN


c[i,j]:=0; FOR k:=1 TO n DO c[i,j]:=c[i,j]+a[i,k]*b[k,j]; END;


WRITELN('матрица A*B :');


FOR i:=1 TO n DO FOR j:=1 TO n DO WRITE(c[i,j]);


WRITELN;


END.


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


FOR i:=1 TO n DO BEGIN


FOR j:=1 TO n DO WRITE(c[i,j]:8);


WRITELN;


END;


Теперь матрица выводится аккуратно.


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


CONST a : ARRAY[1..5] OF Byte=(1,2,3,4,5);


c : ARRAY[0..3] OF Char=('a','b','c','d');


b : ARRAY[-1..1] OF Boolean=(FALSE,TRUE,FALSE);


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


CONST c : ARRAY[0..3] OF Char='abcd';


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


CONST A : ARRAY[1..3,1..2] OF Real = ((0,1),(2,4),(3,5));


Каким именно образом сгруппировать значения элементов, легко понять, вспомнив, что массив ARRAY[1..3,1..2] OF Real есть на самом деле компактная запись описания ARRAY[1..3] OF ARRAY[1..2] OF Real.


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

Сохранить в соц. сетях:
Обсуждение:
comments powered by Disqus

Название реферата: Интервальные типы данных. Оператор TYPE. Массивы

Слов:1579
Символов:12046
Размер:23.53 Кб.