ТОР 5 статей: Методические подходы к анализу финансового состояния предприятия Проблема периодизации русской литературы ХХ века. Краткая характеристика второй половины ХХ века Характеристика шлифовальных кругов и ее маркировка Служебные части речи. Предлог. Союз. Частицы КАТЕГОРИИ:
|
Занятие 1. Комбинированный тип данных. Запись. Описание записи. Доступ к полям записи. Оператор With. Примеры решения задачДовольно часто вполне оправданным является представление некоторых элементов в качестве составных частей другой, более крупной логической единицы. представляется естественным сгруппировать информацию о номере дома, названии улицы и городе в единое целое и назвать адресом, а объединенную информацию о дне, месяце и годе рождения – датой. В языке Паскаль для представления совокупности разнородных данных служит комбинированный тип запись. Запись и массив схожи в том, что обе эти структуры составлены из ряда отдельных компонент. В то же время, если компоненты массива должны быть одного типа, записи могут содержать компоненты разных типов. Приведем пример описания переменной, имеющей структуру записи: Var Address: Record HouseNumber: Integer; StreetName: String[20]; CityName: String[20]; PeopleName: String; End; Отметим, что поля StreetName и CityName имеют одинаковый тип: String[20]. Поскольку в описании эти поля могут располагаться в любом порядке, то можно сократить описание записи с полями одинакового типа. Сокращенное описание записи Address выглядит следующим образом: Var Address: Record HouseNumber: Integer; StreetName, CityName: String[20]; PeopleName: String; End; Каждая компонента записи называется полем. В переменной записи Address поле с именем HouseNumber само является переменной типа Integer, поле StreetName – двадцатисимвольной строкой и т.д. Для того чтобы обратиться к некоторому полю записи, следует написать имя переменной и имя поля. Эти два идентификатора должны разделяться точкой. Оператор, который присваивает полю HouseNumber значение 45, выглядит так: Address.HouseNumber:= 45; Таким же образом присваиваются значения другим полям записи Address: Address.StreetName:= 'Профсоюзная'; Address.CityName:= 'Сургут'; Address.PeopleName:= 'Петрова Алла Ивановна'; Каждое поле записи Address можно рассматривать как обычную переменную, которую можно напечатать или использовать в расчетах. Вместе с тем запись может использоваться как единое целое. В этом случае надо ввести тип записи. Предположим, имеется следующее описание: Type Date = Record Day: 1..31; Month: (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec); Year: Integer; End; Var HisBirth, MyBirth: Date; После приведенного описания переменные HisBirth и MyBirth имеют тип записи Date. Помимо действий над отдельными полями записей HisBirth и MyBirth можно выполнять операции над всей записью. Следующий оператор присваивания устанавливает равенство значений записей HisBirth и MyBirth: HisBirth:= MyBirth; Это присваивание эквивалентно следующей последовательности операторов: HisBirth.Day:= MyBirth.Day; HisBirth.Month:= MyBirth.Month; HisBirth.Year:= MyBirth.Year; Для переменных одного типа можно проверить выполнение отношения равенства или неравенства ("=", "<>"). После выполнения приведенных выше присваиваний следующее булево выражение будет иметь значение True: HisBirth = MyBirth; Рассмотрите пример описания процедуры, которая получает запись в качестве параметра–значения и печатает дату в сокращенной стандартной форме, используя формат (MM-DD-YYYY). Procedure WriteDate(OneDate: Date); Begin Write(Ord(OneDate.Month)+1); Write('-'); Write(OneDate.Day:2); Write('-'); Write(OneDate.Year:4); End; Так как на тип компонент массива не накладывается ограничений, то можно использовать массив, компонентами которого являются записи. Посмотрите описание такого массива: Var Birthdays: Array [1..Persons] of Date; Чтобы обратиться к некоторому полю определенной записи массива, следует определить имя массива, индекс интересующей записи и имя необходимого поля. Например, следующий оператор печатает содержимое поля Year записи Birthdays[3]: Write(Birthdays[3].Year); Примечание. Поля записи в свою очередь тоже могут быть массивами, множествами, записями. Задание. Рассмотрите следующие описания: Type Date = Record Day: 1..31; Month:1..12; Year: 1..9999 End; Reminder = Record Message: Array [1..5] of String; Event: Date End; Var Today: Date; Memos: Array [1..100] of Reminder; Calendar: Array [1..365] of Date; Запишите в тетрадь, какой тип, если он определен, у следующих идентификаторов? а) Today.Year б) Memos [2] в) Memos [4].Month г) Calendar [200] д) Memos [16].Message[2] е) Memos [16].Message[1],[2] ж) Calendar[1].Date з) Memos [10].Event Задание. Составьте программу, организующую ввод наиболее полной информации о людях и вывод интересующей информации на экран. Приведем описание массива, компоненты которого являются записями: Var Payroll: array [1..Workers] of record FirstName, LastName: string; Residence: record HouseNumber: real; StreetName, CityName: string; StateName: Array [1..2] char; ZipCode: integer; end; Phone: record AreaCode, Exchenge: 1..999; Line: 1..9999; rnd; PayScale: 'A'..'G'; end; Отметим, что два поля Residence и Phone являются записями. Как выполнить обращение к полям этих записей? Как распечатать условный шифр рабочего № 7? Поскольку это поле располагается во вложенной записи, то следует указать как имя самой записи, так и имя записи, в которую данная запись входит. write (Payroll[7].Residence.ZipCode); Аналогично приведенное присваивание корректирует шифр рабочего № 23: Payroll[23].Phone.AreaCode:=804; Оператор if, представленный ниже, выполняет проверку инициала рабочего № 58: if Payroll[58].LastName[1] in ['T'..'Z'] Then... Соблюдение всех правил перечисления индексов и имен полей при составлении ссылок является довольно утомительным занятием, часто приводящим к ошибкам. В некоторых программах, содержащих большое количество обращений к одному и тому же полю, такое положение приводит к однообразному повторению. Чтобы облегчить выполнение многократных ссылок для описанных структур вводится оператор With (в переводе с английского – предлог "с"). Общая форма записи: with <имя переменной> do <оператор> В рамках оператора, определяемого внутри оператора With, к полям определяемой переменной можно обращаться просто по имени. Например, with Payroll[7].Residence do ZipCode:= 2345; for i:= 1 to Workers do with Payroll[i] do if PayScale < 'G' then PayScale:= Succ(PayScale); Оператор with позволяет более компактно представлять часто используемые переменные. Посмотрите это на примере фрагмента программы, печатающего адрес рабочего № 14: with Payroll[14].Residence do begin writeln(HouseNumber,' ',StreetName); writeln(CityName,',',StateName,',',ZipCode); end; В рамках составного оператора, следующего за with, каждое обращение к имени поля автоматически связывается с записью Payroll[14].Residence. Печать адресов всех рабочих выполняется при помощи следующего оператора цикла: for i:= 1 to Workers do with Payroll[i].Residence do begin writeln(HouseNumber,' ',StreetName); writeln(CityName,',',StateName,',',ZipCode); end; Операторы with могут быть вложенными. Приведенные ниже три оператора эквивалентны друг другу: 1. Payroll[i].Residence.HouseNumber:= 50; 2. with Payroll[i].Residence do HouseNumber:= 50; 3. with Payroll[i] do with Residence do HouseNumber:= 50; Однако недопустимым является использование вложенных операторов With, в которых указываются поля одного типа, поскольку возникает неоднозначность конструкции. По этой причине приведенное использование вложенных операторов With является неверным: with Payroll[5] do with Payroll[17]do PayScale:='A'; Следует очень внимательно подходить к использованию вложенных операторов With, применение которых не только может привести к ошибкам, но также к потере наглядности структуры программы. Хотя оператор With является стандартным средством сокращения, его полезность должна еще проявиться. Конечной целью всякого хорошего программиста является написание не только короткой, но и понятной программы. Рассмотрите решение задачи. Задача. В массиве хранятся данные об учениках класса: школа, фамилия, класс. Вывести список учеников, которые учатся в восьмом классе. Program LipovsevM; Uses Crt; Type Uchenik=record Shkola: integer; Fam: string[15]; Klass: integer; end; Var I,n,a,j: integer; Massiv: array[1..100] of Uchenik; Рrocedure Poisk; Begin for i:=1 to n do if massiv[i].klass=8 then with massiv[i] do writeln(Shkola:4,' ',Fam:15,' ',klass); End; Begin ClrScr; writeln('Введите число учеников '); write('->'); read(n); for i:=1 to n do begin writeln('Введите через пробел номер школы и фамилию ученика '); write('->'); with massiv[i] do begin readln(Shkola,Fam); write('Введите класс ученика (только число) ->'); read(Klass); end; end; writeln('Ученики 8-ых классов:'); writeln('Школа Фамилия Класс'); writeln('---------------------------------'); Poisk; ReadKey; End. Не нашли, что искали? Воспользуйтесь поиском:
|