Основы программирования на языке Паскаль                          
		             readln;END. 
       Program Prim42;   {программа удаляет все пробелы в строке, стоящие в строке слева, если они имеются}  
         Var  str:string[255];          { Var  str: string; будет работать так же}       function del(stroka:string):string; 
         Var dlina:byte; 
      Begin  dlina:=Ord(stroka[0]); 
             while ((dlina>0)and(copy(stroka,1,1)=' '))do 
             delete(stroka,1,1); 
             del:=stroka; 
      end; 
      BEGIN  writeln('введите строку'); 
             readln(str); 
             writeln(del(str));  readln; 
      END. 
             Program Prim43;   { Даны три исходные строки A,B,C. В строке А определить первую бук } { ву; Затем заменить первую букву строки А со строчной на заглавную; } { объединить в одну строку A,B,C; Определить длины строк A,B,C} { и в результирующей строке вставить '-' между составляющими ее}{ строками. В результирующей строке найти номер позиции, в которой } { буква "а" встречается первый раз; определить длину результирующей } { строки. После каждого действия печатать результаты. }      Var A,B,C:string[14]; str:string[50]; ch:string[1];          d1,d2,d3:integer; 
   Begin  A:='электронная'; B:='вычислительная'; C:='машина';          ch:=copy(A,1,1);             writeln(ch); 
          delete(A,1,1);               writeln(A); 
          writeln(upcase(ch[1])); 
          insert(upcase(ch[1]),A,1);   writeln(A); 
          str:=concat(A,B,C);          writeln(str); 
          d1:=length(A); d2:=length(B); d3:=length(C); 
          writeln('длины строк ' ,d1:6,d2:6,d3:6);          insert('-',str,d1+1); insert('-',str,d1+d2+2); 
                                writeln(str); 
          writeln('первый раз буква "а"стоит в результирующей строке ',                   'в позиции ',pos('а',str));          writeln('общая длина строки  =',length(str)); 
          readln;   END. 
9. Записи
Ранее мы рассматривали структурированные данные, состоящие из компонент одного типа (массивы). Однако на практике часто необходимо иметь под одним именем совокупность данных различного типа. Например, информация о студенте может состоять из данных: фамилия, имя, отчество (тип string), домашний адрес (тип string), пол (тип char), номер группы (тип integer), номер комнаты проживания в общежитии (тип integer), изучаемые предметы (тип, массив строк) и т.д.  
Для объединения разнотипных данных под одним именем и возможности последующей их обработки в языке Pascal предусмотрен тип данных запись. 
Запись - поименованный структурированный тип данных, состоящий из фиксированного количества различных компонент. Определение (описание) данного типа "запись" начинается атрибутом record и заканчивается end.  
Между record и end заключается список компонент записи, называемых полями, с указанием их имен и типа каждого поля. Туре имя типа=record         идентификатор поля: тип компоненты;          идентификатор поля: тип компоненты; 
         end; 
Var идентификатор: имя типа; Возможно и «прямое» описание записи, без предварительного описания типа. Пример описания записи с помощью предварительного задания типа:Туре Car=record      Nomer: integer; {номер}      Marka: string [20]; {марка автомобиля}     FIO: string [40], {ф.и.о. владельца}      adres: string [60]; {адрес владельца}end;Var M, V: Car;Либо «прямое» описание:Var М, V: Record       Nomer: integer;       Marka: string [20]; 
FIO: string [40];      adres: string [60]; end;     Идентификатор поля должен быть уникален только в пределах записи, однако во избежание ошибок лучше его делать уникальным в пределах программы.  
Объем памяти, выделяемый в разделе Var, для хранения записи складывается из объемов памяти - суммы длин полей.       Значения полей записи могут использоваться в выражениях, при этом в них должны указываться составные (уточненные) имена, так как имена полей в различных записях могут совпадать. Например, чтобы получить доступ к полям записи Саr, необходимо пользоваться именами М. FIO, М. NOMER для записи М, а для записи V - именами V. FIO, V. NOMER. Эти имена можно использовать везде, где применяются обычные имена, например, в операторах присваивания:  
М. Nomer:=1678;  
V. Nomer:=3789;  
М. Marka:'газ-24';  
V. Marka:='Таврия';  
В операторах ввода-вывода:  
writeln (м. marka);  
Допускается применение операторов присваивания к записям в целом, если они имеют одинаковые структуры. Так, для приведенного выше описания записей М и V допустимо M:=V;  
После выполнения этого оператора значения полей записи V станут равными значениям полей записи М.  
В ряде задач удобно пользоваться следующими массивами записей: 
Туре Person=record  
     FIO: string [30];  
     Prof: string [30); end;  
  Var List: array [1..50] of Person;  
Здесь массив List будет состоять из 50 записей типа Person.  
Сама запись может иметь поля любого известного нам типа, в том числе и массивного. Допускается, чтобы поле записи само было записью. Обращение к полям записи с помощью составных имен имеет несколько громоздкий вид, что особенно неудобно при использовании мнемонических идентификаторов длиной более 5 символов. Для облегчения этой ситуации в языке Pascal есть оператор with, который имеет следующий формат:  
with имя переменной типа запись do  
begin ···················· end.  
Один раз указав в операторе with переменную типа запись, затем - в пределах begin... end, стоящих после with, можно работать с именами полей этой записи как с обычными переменными, т.е. без указания перед именем поля имени записи. Например:  
без применения оператора with:  
М. NOM:=5543;  
M.MARKA:='гa3-24';  
М. FIO:='Петров П. П.';  
М. Adres:='ул. Чкалова, 7, кв.32';  
end;  
Составить программу учета успеваемости студентов курса, состоящего из шести групп до 30 студентов в каждой группе. Каждый студент сдавал экзамены по пяти дисциплинам: высшая математика, основы информатики, философия, история Украины, архитектура ЭВМ. По каждому предмету можно получить оценки 2, 3, 4, 5. Каждый экзамен можно сдавать до трех раз. Произвести анализ: если у студента имеется три двойки по одному предмету или три непересданные двойки по трем предметам, то он должен быть отчислен; если студент все двойки пересдал, то его нужно поругать.  
              Program Prim44; 
     label u,w; 
     type  mo=array[1..5,1..3] of 0..5; 
          st=record 
             namb:integer; 
             fio:string[20]; 
             o:mo; end; 
     var 
          gr:array[1..6,1..30] of st; 
          i,j,k,l,kol_dvoek,v,kgr,n:integer; 
          md:mo; ch:char; 
          predmet:string;    kst:array[1..6] of byte; 
    procedure rea_ocenki(fio:string;Var oc:mo); 
      Label M1,M2,M3,M4;
      Var i:integer;
        begin
            for i:=1 to 5 do
           Begin
              case i of
            1:predmet:='основы информатики';
            2:predmet:='высшей математике';
            3:predmet:='философии';
            4:predmet:='архитектуре ЭВМ';
            5:predmet:='истории Украины';  end;
              writeln('введите оценку студента  ',fio,' no ',predmet);
   M1: readln(oc[i,1]);
           if (oc[i,1]<2) or (oc[i,1]>5) then
        Begin writeln('введите правильно оценку'); goto M1; end;
         if oc[i,1]>2 then Begin oc[i,2]:=0; oc[i,3]:=0; goto M4; end else
   M2: writeln('введите вторую оценку студента ',fio,' по ',predmet);
       readln(oc[i,2]);
           if (oc[i,2]<2) or (oc[i,2]>5) then
        Begin writeln('введите правильно оценку'); goto M2; end;
         if oc[i,2]>2 then begin oc[i,3]:=0; goto M4; end else
   M3: Writeln('введите третью оценку студента ',fio,' по ',predmet);
       readln(oc[i,3]);
           if (oc[i,3]<2) or (oc[i,3]>5) then
        begin writeln('введите правильно оценку'); goto M3; end;
           M4: end;  end;
   BEGIN                      { начало блока ввода оценок студентов}
       writeln('при вводе оценки набираются: 5, если экзамен');
       writeln('сдан на 5 и, если были пересдачи, то 2,2,3 ');
   z:    writeln('до первой положительной оценки');
   writeln('задайте количество групп, не более 6 ');
   readln(kgr);
            for i:=1 to kgr do      { установка индекса группы }
  begin  case i of                  { определяем группу по i }
         1:n:=610;
         2:n:=611;
         3:n:=612;
         4:n:=613;
         5:n:=614;
         6:n:=615;
           else writeln('неправильно задано количество групп'); goto 2; end; end;
        writeln('задайте количество студентов в группе ',n);
        readln(kst[i]);
            for j:=1 to kst[i] do  { установка номера студента i в группе }
   begin   with gr[i,j] do         { работать без составных имен }
   begin  namb:=n; writeln('введите фамилию ',j,' студента гр. ',namb);
            readln(fio);
            for k:=1 to 5 do           { обнуляем массив оценок }
            for l:=1 to 3 do
            o[k,l]:=0;
            writeln('введите оценки студентов ',fio);
            rea_ocenki(fio,o); end;end;end;
                                { конец ввода оценок студентов }
{ отображение на экране введения оценок }
       for i:=1 to kgr do
       for j:=1 to kst[i] do
    Begin with gr[i,j] do
  Begin     for k:=1 to 5 do
    write(o[k,1],o[k,2],o[k,3],' '); writeln; end; end; 
{ конец вывода на экран оценок  }
                      { начало блока анализа успеваемости студентов }
            for i:=1 to kgr  do          { индекс группы }
            for j:=1 to kst[i] do          { номер студента }
    Begin   kol_dvoek:=0; v:=0;      { работать без составных имен }
            with gr[i,j] do
    Begin
           for k:=1 to 5 do            { номер предмета }
    Begin
   { итак, анализируем состояние успеваемости студента, информация }
   { о котором хранится в записи gr[i,j]; так как мы работаем под уп-}
   {равлением оператора  with gr[i,j], то можно пользоваться не }
   { составными именами полей }
         case k of                  { определить название предмета j }
          1:predmet:='основы информатики';
          2:predmet:='высшая математика ';
          3:predmet:='философия';
          4:predmet:='архитектура ЭВМ';
          5:predmet:='история Украины'; end;
    if o[k,1]=2 then if o[k,2]=2 then if o[k,3]=2 then begin
  writeln('студент ',fio,' группы ', namb,' подлежит отчислению так как');
    writeln('имеет три двойки по предмету ',predmet);
    v:=1; readln; goto w; end                       { на новый предмет }
    else Begin kol_dvoek:=kol_dvoek+2; goto w; end
    else Begin kol_dvoek:=kol_dvoek+1; goto w; end;
  w:   end;
    if v=1 then goto u                             { к новому студенту }
        else if kol_dvoek=0 then goto u
    else Begin
    writeln('студент ',fio,' группы ',namb,' является разгильдяем так как');
    writeln('имеет в зимнюю сессию ',kol_dvoek,' двоек и является');
    writeln('кандидатом на отчисление в весеннем семестре');
      readln;  end; end;
   u: end;  END.
Программа снабжена комментариями, поэтому при внимательном рассмотрении читается легко. Трудности могут возникнуть при разборе блока анализа результатов, поэтому мы приведем блок-схему логической части этого блока (рис. 9.1).  
9.1. Комплексные данные 
При работе с комплексными данными удобно пользоваться записями с двумя полями, первое содержит информацию о действительной части данного, а второе - о мнимой части данного.    
       Program Prim45;  
   Type  complex=record  
         deistv:real; mnim:real;   
end; 
    Var   a,b,c:complex; 
       BEGIN 
          a.deistv:=6.3; 
          a.mnim:=1.9;    END. 
9.2. Запись с вариантами 
Записи, описанные выше, имеют строго определенную структуру. однако есть возможность создавать записи, имеющие несколько вариантов одного и того же поля. Вариантные поля записываются после описания безвариантных полей с помощью оператора Case.  
ТУРЕ  
         zap=record  
                 описание безвариантных полей;  
         Case имя поля: тип имени поля of  
             список констант выбора: (поле,... тип); ...  
             список констант выбора: (поле,... тип);  
end;  
Пример:  
Туре zap=record  
Nomer: byte;                       {фиксированные поля}  
Articul: integer;  
Case Flag: boolean of      {вариантные поля}  
      TRUE: (cena l: integer);  
      FALSE: (cena 2; real);  
end;  
Var P, Si Zap;  
поле Cena l доступно только тогда, когда Flag=TRUE 
поле Cena 2 доступно только тогда, когда Flag=FALSE  
При использовании записей с вариантами необходимо придерживаться следующих правил:  
все имена полей должны отличаться друг от друга, даже если они встречаются в различных вариантах; 
запись может иметь только одну вариантную часть, причем вариантная часть должна размещаться в конце её;  
Если поле, соответствующее какой-либо метке, является пустым, то оно записывается следующим образом:  
список констант выбора: ( );  
         Program Prim46; 
    Type zap=record 
              nomer:byte; 
              artikul:integer; 
           case flag:boolean of 
              true:(cena1:integer); 
              false:(cena2:real); end; 
    Var h,s:zap; 
  BEGIN  with h do 
    Begin nomer:=1; artikul:=2345; flag:=true; cena1:=25; 
      writeln('nomer=',nomer,' artikul=',artikul,' cena1=',cena1); 
          flag:=false; cena2:=3.2; 
      writeln('cena2 ',cena2); 
       end; readln; END. 
10. Файлы
10.1. Общие замечания 
В практике программирования часто встречаются задачи, решаемые с применением малоизменяемых во времени данных. К ним относятся, например, задачи бухгалтерского учета оптимального планирования и т.п. Ввод данных с клавиатуры при каждом счете задачи очень трудоемок, а иногда просто невозможен из-за временных ограничений. Для решения этой проблемы в языках программирования реализована концепция файлов, что позволяет после разового набора информации запомнить ее на внешнем носителе и обращаться к ней непосредственно из обрабатывающих программ при каждом счете задачи.  
Файл - поименованная область памяти, как правило, на внешнем носителе, предназначенная для хранения информации. файл можно также считать структурированным типом данных, состоящим из последовательности компонент одного и того же типа и одинаковой длины и структуры. чаще всего компонентами файла являются записи.  
Файл может быть связан с внешним носителем информации, т.е. располагаться на магнитном или СД диске, магнитной ленте, клавиатуре при вводе информации или на экране, принтере и при выводе её и т.д.  
Файлы бывают стандартными, т.е. определенными разработчиками или администраторами операционной системы или вычислительной среды, а также пользователем, т.е. человеком, составляющим программы в каком-либо алгоритмическом языке (например в Pascal), или с помощью других программных продуктов (баз данных, редакторов и т.д.).  
Каждый файл имеет свое имя, которое зарегистрировано в соответствующей директории (оглавлении).  
Определение файлового типа строится по такой схеме:  
Туре имя типа=file of тип компонент;  
Var идентификатор,.., идентификатор: имя типа;  
Например:  
Туре zap=record  
Nom: integer;  
FIO: string [20]; 
oklad: real; end; 
Ft=file of zap;  
Var a, b, с: Ft;  
Описаны три файла с именами а, b, с типа Ft. Компонентами файлов служат записи типа zap. Другими словами, файл схематично можно представить в виде «ленты» компонент, каждая из которых является записью типа zap. Доступ к компонентам файла может быть последовательным и прямым. Последовательный доступ - это когда для обращения к n-й компоненте необходимо «посмотреть» n-1 компонент; прямой доступ - обращение к компоненте идет прямо по «ключу» (номеру компоненты), без «просмотра» предыдущих компонент.  
При работе с файлом «внимание» машины сосредоточено на компоненте, определенной указателем файла (этой компонентой будет работать машина при следующем обращении к файлу).  
Имя файла должно быть уникальным и состоящим из собственного имени и необязательного расширения - типа файла, содержащего три символа и отделенного от основного имени точкой. Расширение, как правило, указывает в мнемонической форме на содержимое файла: pas, ехе, txt и т.д. В некоторых случаях тип файла присваивается автоматически операционной системой или используемым пакетом.  
Каждый диск, содержащий файлы, имеет оглавление, в которое помещается информация о его имени, расширении, времени и дате его создания, о местонахождении на физическом носителе (например, на диске С или D).  
Для поиска файла необходимо указать диск, каталог, подкаталог, имя файла, его расширения.  
Например: C:\TURBO\Prim\Prim46.pas. 
Здесь файл Prim 46.pas находится в подкаталоге Prim каталога TURBO диска С. 
 
10.2. Стандартные процедуры и функции для работы с файлами 
Далее примем обозначения: FV - имя файловой переменной или просто имя файла, str - строковое выражение, Р - имя структурной компоненты файла, n - целое выражение.  
Assig и (FV, str); - процедура присвоения имени файла.  
Имя файла, которое является значением str, присваивается переменной файлового типа FV. Далее все действия над этой переменной будут эквивалентны действиям над файлом, определенным именем str. Например: Assign (books, 'c:\bibl.dos'); позволяет работать не с именем 'c:\bibl.dos', которое может быть достаточно длинным (если имеются каталоги и подкаталоги), а с именем books.  
Rewrite (FV); - процедура создания нового файла с именем FV на диске. Имя файла должно быть предварительно определено процедурой Assign. Если на диске уже был файл с таким именем, то он уничтожается. Указатель файла устанавливается в первую позицию с номером 0. Файл еще не содержит ни одной компоненты, а только подготовлен к загрузке.  
Reset (FV); - процедура открытия (разрешение работать с файлом именем FV) уже имеющегося файла. Указатель устанавливается на начало файла, в позицию с номером 0.  
Read (FV, Р); - процедура чтения компоненты файла, на которую установлен указатель, ее содержимое помещено в область памяти с именем Р.  
Write (FV, Р); - процедура записи информации из области памяти Р в файл FV и компоненту, на которую установлен указатель.  
Seek (FV, n); - процедура установки указателей на компоненту с номером n.  
Flush (FV); - очищение буфера сектора. Выполнение процедуры приводит к выталкиванию содержимого внутреннего буфера (области памяти) в файл.  
Close (FV); - процедура закрытия файла, при этом записывается маркер конца файла. После работы с файлом его необходимо обязательно закрыть.  
Erase (FV); - процедура уничтожения файла. Если производится уничтожение открытого файла, его необходимо предварительно закрыть.  
Rename (FV, str); - процедура переименования файла. Файлу FV присваивается имя str.  
Truncate (FV); - процедура уничтожения всех компонент файла, начиная с места текущего положения указателя и подготовки файла к записи.  
Eof (FV) - функция проверки маркера конца файла. Значение функции равно True, если указатель файла находится за последней компонентой, и False - в противном случае.  
Filepos (FV) - функция определения положения указателя.  
Filesize (FV) - функция определения длины файла. Функция возвращает целочисленное значение, равное количеству компонент файла: если File Size (FV) = 0, то файл пуст.  
Loresult (FV) - функция проверки результата последней операции ввода- вывода на наличие ошибок. Если ошибка обнаружена, возвращается код ошибки, если нет, то код = 0.  
 
10. 3. Стандартные файлы 
Con: - консоль (клавиатура или экран дисплея). Турбо-Паскаль устанавливает различия между этими устройствами по направлению передачи данных: чтение данных возможно только с клавиатуры, а запись - только на экран. Ввод с клавиатуры буферизуется: символы по мере нажатия клавиш помещаются в буфер, содержимое которого передается в ЭВМ только после нажатия клавиши ENTER, поскольку вводимые и буферизированные символы отображаются на экране. Con применяется «по умолчанию» для ввода с помощью операторов READ и Readln и для вывода на экран - операторов write и writeln, если не указано имя файла FV.  
Все внешние устройства ЭВМ трактуются в Pascal как логические устройства, имеющие имена файлового типа и которым соответствуют заранее определенные (стандартные) файлы. Идентификацию (отождествление) устройства и стандартного файла осуществляют специальные программы (драйверы), которые обеспечивают выполнение операций ввода-вывода между процессором и конкретным физическим устройством. Ниже указаны имена файлов и соответствующие им устройства так, как они определены разработчиками системы.  
Trm: - терминал, предназначенный для ввода с клавиатуры и вывода на экран без редактирования.  
Kbd: - клавиатура, используемая только для ввода с клавиатуры, при вводе информация не отображается на экран.  
PRN: - построчно печатающее устройство (принтер), используемое только для вывода.  
Aux: - вспомогательное устройство, подключающееся через порты.  
Usr: - устройство пользователя, применяемое при написании собственных драйверов для организации нестандартного ввода-вывода.  
10.4. Файлы последовательного доступа, созданные пользователем 
Работа с файлом последовательного доступа предполагает его создание, обработку и корректировку. Для создания файла последовательного доступа необходимо:  
объявить файловую переменную;  
«привязать» файл к физическому носителю информации (присвоить файлу имя). (Assign);  
открыть новый файл (Rewrite);  
подготовить информацию для ввода в компоненту файла, т.е. сформировать запись для ввода в файл в качестве компоненты;  
записать в файл компоненту (Write);  
повторить п. 4, 5 необходимое количество раз;  
закрыть созданный файл (Close).  
Для доступа к компонентам последовательного файла (например, для просмотра содержимого файла на экране или для обработки компонент в целях включения их в качестве фрагментов в программу обработки каких-либо данных и т.п.) следует:  
присвоить файлу имя (Assign);  
открыть уже существующий файл (Reset);  
считать текущую компоненту из файла в рабочую область памяти (как правило, типа запись со структурой компоненты), (Read);  
выполнить обработку информации (например, вывести на экран поля записи);  
закрыть файл (Close).  
Возможны три типа корректировки файла как прямого, так и последовательного доступа:  
1. Расширение файла за счет внесения новых компонент.  
2. Полная замена содержимого компоненты.  
3. Замена каких-либо полей отдельных компонент.  
Замена содержимого компонент отдельных записей или замена полей отдельных записей будет рассмотрена в следующем подразделе при изучении корректировки компонент файлов прямого доступа.  
Добавление новых записей в файл последовательного доступа выполняется путем записи компонент в конце файла. Маркер конца файла при этом переносится. Естественно, на физическом носителе при этом должно иметься свободное пространство.  
Для записи новых компонент в конце имеющегося файла необходимо:  
присвоить файлу имя (Assign);  
открыть уже существующий файл (Reset);  
установить указатель файла за последней компонентой (Seek (FV, File sise (FV)):  
создать в специально выделенной области памяти (как правило записи) новую компоненту; 
записать новую компоненту в файл (write);  
закрыть файл (Close).  
Пример. Организовать последовательный файл с именем PRIM bibl.dos в подкаталоге Prim каталога TURBO на диске С, т.е. C:\TURBO\bibl.dos. Компонента должна иметь структуру: индекс книги, порядковый номер экземпляра, фамилию, инициалы первых трех авторов (если их несколько), название книги. Блок создания файла оформить в виде процедуры с именем org. Блок доступа к компонентам файла оформить в виде процедуры с именем obr., а блок корректировки - в виде процедуры с именем Rash.  
             Program Prim47; 
    type books=record              {базовая запись} 
           nomer:integer; 
           avtor:string[16]; 
           nazv:string[30]; 
           index:integer;     end; 
      var  bf:file of books;       { описать файловую переменную } 
           rb:books;               { участок памяти со структурой } 
                                   { компоненты файла } 
   procedure org; 
        begin  assign(bf,'C:\TURBO\PRIM\bibl.dos'); 
               Rewrite(bf); 
          with rb do          { работать с записью rb без уточненных имен } 
          while True do 
        begin   writeln('ввести номер книги'); 
                   readln(nomer); 
              if nomer=9999 then  {9999 - признак окончания ввода данных} 
               Begin  close(bf);  Exit end; 
                   writeln('ввести имя автора'); 
                   readln(avtor); 
                   writeln('ввести название книги'); 
                   readln(nazv); 
                   writeln('ввести значение индекса'); 
                   readln(index); 
                   write(bf,rb); { записать компоненту из rb в файл } 
        end; end; 
    procedure Obr; 
       Begin  Assign(bf,'C:\TURBO\PRIM\bibl.dos'); 
             Reset(bf); 
             with rb do 
             while not Eof(bf) do{ выйти из цикла, когда закончится файл } 
         begin read(bf,rb); 
             writeln(nomer:5,avtor:16,Nazv:10,index:6); { вывод на экран } 
        end; Close(bf);  end; 
    procedure Rash; 
       begin Assign(bf,'C:\TURBO\PRIM\bibl.dos'); 
             Reset(bf); 
             Seek(bf,Filesize(bf)); { установить указатель на конец файла } 
             with rb do 
             while True do 
         begin writeln('ввести номер');          readln(nomer); 
Страницы: 1, 2, 3, 4, 5, 6, 7, 8 
	
	
					
							 |