Организация данных в ЭВМ и основы программирования (1017140), страница 11
Текст из файла (страница 11)
Пример. Для 1-ой экзаменационной ведомости (списка 1) оператор присоединения можно записать так:
With C1 do
Begin
Read(N);
Summa := Ball[1] + Ball[3];
End;
Пример. Имеется ведомость учащихся с оценками:
Иванов Иван 2
Петров Пётр 2
Сидоров Сидор 3
Составить программу для вычисления среднего балла.
Поскольку в каждой строке ведомости представлены данные различного типа, введём запись с именем СПИСОК, состоящую из двух полей:
Name – фамилия и имя – упакованный массив из 15 символов;
Ball – оценка – целое число.
Для вычисление среднего балла Midball находится сумма всех оценок Summa, которая делится на число студентов N.
Program W123;
Const N = 3; (* число учащихся в списке *)
M = 15; (* максимальная длина Name *)
Type T = Record
Name: Packed Array [1..M] of Char;
Ball: Integer;
End;
Var Spisok: T;
I, K: Integer; (* параметры цикла *)
Midball: Real; (* средний балл *)
Summa: Integer; (* сумма оценок *)
Begin
Summa := 0;
Writeln(‘ введите таблицу ‘);
For I := 1 to N do
Begin
For K := 1 to M do
Read(Spisok.Name[K]);
Read(Spisok.Ball);
Summa := Summa + Spisok.Ball;
End;
Midball := Summa / N;
Writeln(‘----------------------------‘);
Writeln(‘ средний балл = ‘, Midball: 5: 2);
End.
Описание записи сделано в разделе Type, где Т – имя типа. В разделе переменных Var указано, что переменная СПИСОК тип Т.
Раздел операторов состоит из двух циклов: один вложен в другой. Внешний цикл с параметром I выполняется столько раз, сколько имеется фамилий в ведомости (в данном случае N = 3). Внутренний цикл с параметром К предназначен для ввода фамилии и имени. На фамилию и имя отводится поле из 15 позиций. Лишние позиции поля заполняются пробелами. Внутри поля фамилию и имя можно располагать свободно, например:
_ _ _ _ Иванов _ Иван
или _ _Иванов _ Иван_ _
или _ _ _Иванов _ Иван_
или _ Иванов_ _ Иван_ _
После имени следует оценка.
Пример. Присвоить звание “отличник” тем, у кого по всем предметам пятёрки.
Из исходного списка С1, в котором содержатся фамилии и оценки, нужно сформировать другой список С2, состоящий из отличников. Для формирования списков используется массив массивов.
Program otl;
Const K = 5; (* количество человек *)
Type Tip = Record
Name: Array [1..K, 1..15] of Char;
Math: Array [1..K] of Integer;
Phis: Array [1..K] of Integer;
Chem: Array [1..K] of Integer;
End;
Var C1, C2: Tip; (* списки *)
I, J, N: Integer; (* параметры циклов *)
Begin
J := 0;
Writeln(‘ введите фамилию и оценки: ‘);
For I := 1 to K do
Begin
For N := 1 to 15 do Read(C1.Name[I, N]);
Read(C1.math[I], C1.Phis[I], C1.Chem[I]);
If (C1.Math[I] = 5) And
(C1.Phis[I] = 5) And
(C1.Chem[I] = 5) then
Begin
J := J + 1;
C2.Name[J] := C1.Name[I];
End;
End;
If J = 0 then Writeln(‘нет отличников ‘)
else Begin
Writeln(‘-----------------------‘);
Writeln(‘отличники:‘);
For I := 1 to J do
Writeln(C2.Name[I]);
End;
End.
Пример. Дан многочлен 4А + 5В – 8С + 16А – 3А + 9К – 1А
Найти подобные члены для переменной А и вычислить суммарный коэффициент. Один элемент многочлена можно считать записью, так как он состоит из данных различного типа – коэффициента (число) и буквы.
Введём обозначения:
М1 – элемент многочлена (запись),
М2 – результирующий элемент (запись),
Coef – коэффициент (элемент записи),
Buk – буква (элемент записи),
Elem – тип записи,
Sum – сумму коэффициентов.
Program Ex4;
Type Elem = Record (* тип элемента *)
Coef: Integer; (* коэффициент *)
Buk: Char; (* буква *)
End;
Var M1: Elem; (* входной элемент *)
M2: Elem; (* выходной элемент *)
Sum: Integer; (* сумма коэффициентов *)
Begin
Sum := 0;
Writeln(‘ введите многочлен ‘);
While Not EOLN do (* end of line *)
Begin
Read(M1.Coef, M1.Buk);
If M1.Buk = ‘A’ then Sum := Sum + M1.Coef;
End;
M2.Coef := Sum;
M2.Buk := ‘A’;
Writeln(‘подобный член = ‘, M2.Coef: 3, M2.Buk);
End.
Запись - это комбинированный тип, сложная переменная с несколькими компонентами. В отличие от массивов компоненты записи (поля) могут иметь разные типы, и доступ к ним осуществляется не по индексу, а по имени поля.
Записи могут входить в качестве компонентов в другие переменные, например, можно сформировать массив записей.
К каждому компоненту записи можно обратиться, используя имя переменной типа записи и имя поля, разделённых точкой.
В области действия оператора присоединения With имена переменных-записей и полей, указанные в его заголовке, можно опускать. Транслятор автоматически формирует полные имена. В области действия оператора присоединения нельзя изменять элементы списка переменных-записей и полей, указанные в заголовке.
Пример. Определить число студентов 1974 г. рождения.
Type Student = Record
Name: Array [1..15] of Char;
Date: Integer;
End; { of record }
Var Grope: Array [1..30] of Student;
K, I: Integer;
Begin
K := 0;
For I := 1 to 30 do
With Grope[I].Date do
If Date = 1974 then K := K + 1;
Writeln(K);
End.
В данном примере в заголовке оператора With стоит Grope[I] – элемент массива, зависящий от параметра I, поэтому оператор присоединения вставлен внутрь цикла по I.
7.3. Записи с вариантами
При определении комбинированного типа в него можно включать вариантную часть. Это означает, что разные переменные, хотя они и относятся к одному типу, могут иметь различные структуры. Например, пусть необходимо задать информацию о некотором человеке, указав фамилию и год рождения, а также, если это мужчина, то сообщить, военнообязанный ли он и какую имеет специальность; если это женщина, то указать, замужем ли она и сколько имеет детей:
Type Pol = (Mug, Gen);
Chel = Record
Fam: Array [1..10] of Char;
God: 1900..2000;
MG: Pol; { заголовок вариантной части }
Case Pol of
Mug: (Voen: Boolean; Spec: Array [1..15] of Char);
Gen: (Zamugem: Boolean; Dety: Integer);
End; (* of record *)
Var Ch1, Ch2: Chel;
Вариантная часть записи начинается оператором Case и следует за общей частью; после её окончания в записи не появляться никакие другие поля, поэтому оператор Case не закрывается служебным словом End.
Обычно некоторое поле общей части указывает вариант. В примере это поле MG, называемое полем признака или дискриминации.
Все варианты описываются внутри оператора Case. Каждый вариант характеризуется задаваемым в скобках списком описаний присущих ему компонентов.
Перед списком стоит одна или несколько меток. Тип этих меток указывается в заголовке вариантной части (в отличие от оператора варианта, где селектором варианта является выражение, а не тип). Тип должен быть скалярным (не массивы и не записи), При этом он задаётся именем.
В явном виде указывать тип в заголовке не разрешается.
Часто для сокращения записи поле признака (дискриминант) включается в заголовок вариантной части:
Case MG: Pol of
Для переменной Ch1 типа Chel можно написать следующие операторы присваивания:
Ch1.Fam := ‘Solomatin’;
Ch1.God := 1977;
Ch1.MG := Mug;
Ch1.Voen := True;
Ch1.Spec := ‘Programmist’;
Задав значение поля признака MG (некоторую константу типа Pol), можно присваивать новые значения только полям вариантной части, помеченных такой же константой.
Хотя никакого контроля поля селектора при обращении к компоненту из вариантной части не производится, для надёжности работы программы следует придерживаться этого правила.
В любой записи может быть только одна вариантная часть, и, если она есть, она должна располагаться за всеми фиксированными полями.
Пример.
Type Alfa = Array [1..10] of Char;
Variety = (Book, Journal, Newspaper);
Name = Record
First, Last: Alfa;
End; (* of Name *)
Edition = Record
Name1: Name;
Title, Publishers: Alfa;
Case V: Variety of
Book: (Years: Integer);
Journal: (Number: 1..12;
Volume: Integer;
YearJ: 1900..2000);
Newspaper: (Day: 1..31;
Month:1..12;
YearN: Integer);
End; (* of Edition *)
………………………
Var E: Edition;
…………………….…
E.Name1.First := ‘Niklau’;
E.Name1.Last := ‘Wirth’;
E.Title := ‘Pascal’;
E.Publichers := ‘Springer’;
E.V := Journal;
E.Number := 5;
E.Volume := 12;
E.YearJ := 1972;
В описании записи разрешается использовать только одну вариантную часть, причём она должна быть записана после фиксированной части. Однако в вариантной части, в свою очередь, может появиться вариантная часть, следовательно, могут быть вложенные друг в друга вариантные части.
При записи варианта обязательно присутствие круглых скобок, даже если в них ничего не заключается. В этом случае записывается просто: ( ).
Пример. Определить площадь геометрической фигуры.
X и Y – координаты одного из углов прямоугольника или треугольника или центра окружности.
Area – площадь.
Skew – угол наклона одной из сторон прямоугольника.
Side1 и Side2 – длины двух смежных сторон прямоугольника.
Inclin – угол наклона одной из сторон треугольника.
Side – её длина.
Angle1 и Angle1 – углы, образованные с нею двумя другими сторонами.
Diameter – диаметр окружности.
Program Opr;
Const Pi = 3.141592;
Type Figure = (Triangle, Rectangle, Circle);
GeometricFigure = Record
X, Y: Real;
Area: Real;
Case Shape: Figure of
Triangle: (Inclin, Side, Angle1,Angle2: Real);
Rectangle: (Skew, Side1, Side2: Real);
Circle: (Diameter: Real);
End; (* of record *)
Var GFig: GeometricFigure;
Begin
……………
Case GFig.Shape of Triangle: GFig.Area := 0.5*SQR(GFig.Side)/(cos(GFig.Angle1)/
sin(GFig.Angle2)+cos(GFig.Angle2)/sin(GFig.Angle1));
Rectangle: GFig.Area := GFig.Side1 * GFig.Side2;
Circle: GFig.Area := Pi * SQR(GFig.Diameter) / 4;
End; (* of Case *)
…………………….
End.
8. ТИПИЗИРОВАННАЯ КОНСТАНТА
Типизированную константу можно использовать как переменную. Её следует рассматривать как инициализированную переменную, значение которой задано с самого начала. Применение типизированных констант экономит машинное время, т.к. начальное присвоение значений уже выполняется компилятором.
Типизированные константы задаются, как обычные, но дополнительно они получают и свой тип. Заданные значения имеются в распоряжении программы только при новом ее пуске, а затем могут изменять свое значение. Повторный пуск программы не с самого начала может дать уже другие значения.
Преимущество применения типизированных констант заключается в простоте присвоения начальных значений для переменных.
Синтаксис (вид описания):
Const имя: тип = значение;
8.1. Простая типизированная константа
Задается как простая переменная.
Пример: Const A:Integer=1267;
Kol:Real=12,32;
Sim:Char =’Z’
B:Char=Ord(65);
Типизированные константы разрешается использовать вместо переменной в виде параметров в подпрограммах.
Типизированная константа представляет собой переменную с заданным значением. Её нельзя использовать в описании других констант или типов.
Пример: Const X:Integer=0;
Y:Integer=50;
Type Mas: Array [X..Y] of Integer; это недопустимо.
8.2. Структурированная (сложная) типизированная константа
8.2.1. Типизированная константа массива
Пример:
Type Sost = (cold, warm, hot);
Massiv = Array [Sost] of string[5];
Const S: Mas = (‘cold’, ‘warm’, ‘hot’);
В примере описывается константа Sost, которую можно использовать для преобразования значений типа перечисления в их соответствующие строковые представления:
Sost[cold]=’cold’
Sost[warm]=’warm’
Sost[hot]=’hot’
Каждый тип, кроме типа массива и указателя, представляет собой допустимый тип компонентов константы массива. При типах массива Character разрешены отдельные символы и символьные цепочки.
При описании типизированной много размерной константы массива каждый размер каждый размер заключается в отдельную пару скобок, а пары отделяются друг от друга запятыми, причем средняя константа соответствует размеру, наиболее далеко отстоящему с правой стороны.
Пример:
Type Massiv = Array [0..1,0..1,0..1] of Integer;
Const chislo: Massiv = (((0,1),(2,3)),((4,5),(6,7)));
Begin
Writeln(chislo[0,0,0],’=0’);
Writeln(chislo[0,0,1],’=1’);
Writeln(chislo[0,1,0],’=2’);
Writeln(chislo[0,1,1],’=3’);
Writeln(chislo[1,0,0],’=4’);
Writeln(chislo[1,0,1],’=5’);
Writeln(chislo[1,1,0],’=6’);