Pascal: Занятие № 9. Типы данных пользователя Паскаль Type

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

Создание типов данных пользователя в Pascal

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

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

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

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

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

Пример: Задана матрица размерностью 10 x 50. Выполнить описание матрицы, используя пользовательский тип данных
1
2
3
4
const  n = 10;
       m = 50;
type matr = array [1..n, 1..m] of integer;
var  a : matr;

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

Например, при описании процедур с параметрами считается неверным писать:

1
procedure p(a: array[1..10] of Integer);

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

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

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

1
2
3
4
5
type
    vector = array[1..10] of integer;
    matritsa = array[1..8] of vector;
var
  ...

Три варианта описаний матрицы эквивалентны:

  1. 1
    2
    
    type  vector = array[1..10] of integer;
          matritsa = array[1..8] of vector;
  2. 1
    
    type  matritsa = array[1..8] of array[1..10] of integer;
  3. 1
    
    type  matritsa = array[1..8,1..10] 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 1: Заданы массивы а[1…5], b[1…10] и c[1…15]. Найти среднее арифметическое минимальных элементов массива (использовать процедуру формирования массива (элементы должны генерироваться случайно) и процедуру определения минимального элемента).
При описании процедур использовать пользовательские типы данных.

Пример результата:

массив 1: 5 1 8 5 6
min = 1
массив 2: 3 9 7 5 9 4 6 9 2 7
min = 2
массив 3: 5 1 9 1 2 9 3 4 7 1
min = 1

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

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

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

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

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

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

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

где

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

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

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

    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.

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

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

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

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

      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.

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

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

      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 2: Определить по названию дня недели выходной ли это или рабочий день.

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

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

    Использование интервального типа в качестве диапазонного ограничителя

    Пример:
    Поезд отправляется в путь в 22 часа и находится в пути 10 часов. Во сколько он прибывает на место назначения?

    Следующий пример продемонстрирует неправильное решение данной задачи:

    1
    2
    3
    4
    5
    6
    
    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(pribitie)
    end.

    Зная об ошибке, теперь можно ее исправить.

    Пример: В зависимости от знака зодиака выдавать к какой стихии он относится:

  • Огонь (Овен, Лев, Стрелец)
  • Воздух (Весы, Водолей, Близнецы)
  • Вода (Рак, Скорпион, Рыбы)
  • Земля (Козерог, Телец, Дева)
  • Показать решение:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    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: В зависимости от названия цветка, выдавать к какому сезону года он относится: 

  • Весна: подснежник, ирис, нарциссы
  • Лето: ромашка, одуван, мак
  • Осень: астра, хризантема, флокс