| Основы программирования на языке Паскаль                                  for i:=1 to n do         for j:=1 to m do       begin writeln('ввести a[',i,',',j,'] элемент матрицы а');             readln(a[i,j]); end;          for j:=1 to m do       begin writeln('ввести b[',j,'] элемент вектора b');             readln(b[j]); end;     for i:=1 to n do       {начало перемножения матрицы на вектор}   begin c[i]:=0;     for j:=1 to m do      c[i]:=c[i]+ a[i,j]*b[j]; end;                            {конец перемножения матрицы на вектор}      writeln('распечатка массива а');        for i:=1 to n do           Begin writeln;         {начать новую строку}        for j:=1 to m do write(' ',a[i,j]); end;       writeln;      writeln('распечатка массива b');           for j:=1 to m do      write('  ',b[j]);               writeln;      writeln('результирующий массив с');           for i:=1 to n do      write('  ',c[i]);              readln;     END. Программа Prim 29a тоже перемножает матрицу на вектор. Здесь матрица может иметь размеры до 50х70, соответственно вектор B может иметь размер до 70, а вектор С - размер до 50 элементов. 7. Подпрограммы7.1. Общие положения В практике программирования часто встречаются ситуации, когда одну и ту же группу операторов необходимо выполнить в различных местах программы, неважно, что при этом по-разному будут называться исходные данные и результаты работы этих операторов. Важно, что эти группы операторов выполняют одну и ту же работу. Например, в различных местах программы необходимо вычислить корни квадратного уравнения, причем в одном месте это будет уравнение ax2+bx+c=0, в другом  - sz2+tz+p=0, в третьем - ky2+ly+n=0 и т.д. В этом случае алгоритм вычисления корней уравнения в программе можно писать один раз в виде подпрограммы, а использовать его многократно. Блок-схема такой программы без применения подпрограммы изображена на рис. 7.1. Блок-схема алгоритма с использованием подпрограммы изображена на рис. 7.2. Подпрограммой называется имеющая имя логически законченная группа операторов  (возможно со своими описаниями), к которой по имени можно обратиться для выполнения неограниченное количество раз из различных мест основной программы, возможно, с различным, но фиксированным набором входных величин и результатов. Подпрограммы могут быть оформлены в виде функций и процедур. Функции применяют тогда, когда результат работы подпрограммы один. Обращение к функции может записываться в выражениях, например: (а+b)/cos(x). Здесь cos(x) есть обращение к подпрограмме типа "функция", правда, стандартной, а не написанной пользователем. Встретив имя cos, машина с входной величиной x обращается к подпрограмме, вычисляет с помощью ряда функцию cos(x) (см. программу в подразд. 4.4.), и результат этой работы в виде значения функции возвращается в арифметическое выражение.      Функция может иметь несколько входных параметров, но всегда один результат. Процедура также может иметь несколько входных параметров, но несколько результатов. Несколько - это 0, или 1, или 2, или 3 и т.д. результатов. Обращение к процедуре состоит из отдельного оператора. Например, обращение к процедуре, вычисляющей корни квадратного уравнения, может иметь вид:    root(a, b, c, x1, x2); Подпрограммы, как функции, так и процедуры могут быть стандартными, например sin(x), cos(x), sqrt(x), succ(y), ord(y) и т.п.; библиотечными, которые становятся доступными при подключении модулей и библиотек (см. далее), а также определены пользователем, т.е. написаны программистом для решения своей задачи.  
 7.2. Подпрограммы-функции, определенные пользователем Функции пользователя описываются в разделе описания функций и процедур основной программы. Описание функции строится как законченная программа, т.е. может состоять из заголовка и шести разделов: описания, меток, констант, типов, переменных, функций и процедур и раздела операторов. Заканчивается описание функции символом точка с запятой. Написать программу, вычисляющую с помощью подпрограммы-функции, выражение: f1(x)=x+256.4; f2(y)=y+256.4; f3(z)=z+256.4;           Program Prim30;   Var         x,y,z,f1,f2,f3:real;   function f(x:real):real;        {заголовок функции;}                                   { f - имя функции, это же и имя}                              {результата, х - формальный параметр}     Begin f:=(x+256.4); end;      {тело функции}  BEGIN                            {начало основной программы}        writeln('ввести x,y,z'); readln(x,y,z);   f1:=f(x);  {обращение к подпрограмме f с фактическим параметром x}   f2:=f(y);  {обращение к подпрограмме f с фактическим параметром y}   f3:=f(z);  {обращение к подпрограмме f с фактическим параметром z}           writeln(f1:20,f2:20,f3:20); readln;   END.  Написать программу, вычисляющую G: Оформим вычисления  в виде подпрограммы-функции:       Program Prim31;     Var    h,x,y,z,g:real;   function f(a,b:real):real; {входные формальные параметры a,b}      Begin         f:=sqr(ln(a)+sin(b))/(cos(a)*exp(b));                              end;  BEGIN  writeln ('введите положительные h,x,y,z');         readln(h,x,y,z);    if (x>=1) and (x<3)  then writeln('g=',h+f(x,y)) else;    if (x>=3) and (x<5)  then writeln('g=',sqrt(h)+f(z,x)) else;    if (x>=5) and (x<=9) then writeln('g=',sqr(h)+f(y,z)) else;                              writeln('g=0');              readln;   END. В этой программе описание формулы начинается словом function, имя функции f, результат вычисления функции типа real. Тело функции заключено в операторные скобки begin, end; a, b называются формальными параметрами. В данной функции нам не понадобились разделы описаний. При выполнении основной программы, которая начинается begin, встречается выражение f(x, y). Встретив такое выражение, машина по имени f определяет, что это обращение к функции. затем машина проверяет совпадение количества и типа фактических параметров (x, y) с формальными (a, b). При их совпадении в тело функции вместо формальных параметров подставляются фактические и тело выполняется, полученный результат используется при вычислении выражения, стоящего в операторе writeln. Составить программу вычисления при условии, что а<b: Если a и b не укладываются в заданные пределы, нужно сообщить об этом пользователю и спросить, будут ли другие диапазоны -- ответ: "Y, N". Если заданы не те буквы (y, n), повторить вопрос. Прежде чем писать программу, определимся с функциями:   оформим в виде функции f1;   - в виде f2; sin(x)+f1   - в виде f3; cos(x)+f1  - в виде f4; cos(x)-f2   - в виде f5; вычисления    по методу трапеций с точностью 0.1 oформим в виде подпрограммы-функции f6.     Program Prim32;        label NAH,P;         Var   b,a,z:real;               lit:char;            function f1(x:real):real;              Begin f1:=exp(x/10)+sqrt(x/(x+3)); end;            function f2(x:real):real;              Begin f2:=sqrt(sqr(x)/(3*x+10)); end;            function f3(x:real):real;              Begin f3:=sin(x)+f1(x); end;            function f4(x:real):real;              Begin f4:=cos(x)+f1(x); end;            function f5(x:real):real;              Begin   f5:=cos(x)-f2(x); end;        function f6(a,b:real):real;            label K,N1,K1,KC,T;            Var  h,s1,s,x:real;  i,n:integer;        Begin              s1:=9.999e+10; n:=10;      N1:     h:=(b-a)/n; s:=0; x:=a;            for i:=1 to n do         Begin  if a>b then goto t else          if (0<=a)and(b<5)    then Begin s:=s+(f3(x)+f3(x+h))/2*h;                            goto kc; end      else          if (5<=a)and(b<10)   then Begin s:=s+(f4(x)+f4(x+h))/2*h;                            goto kc; end      else          if (10<=a)and(b<=16) then Begin s:=s+(f5(x)+f5(x+h))/2*h;                            goto kc; end      else  goto t;   KC:    x:=x+h; end;          if abs(s-s1)<0.1 then goto k            else   Begin s1:=s; n:=n*10; goto n1; end;   K:  f6:=s; goto k1;   T:  writeln('пределы интегрирования не соответствуют условию');       f6:=-9999999999.;   K1: end;  BEGIN   NAH:  writeln('введите значения a,b');         readln(a,b); z:=f6(a,b);       if z=-9999999999. then goto p;         writeln('z=',z);      P:  readln;        writeln(' будем еще вычислять z ? , если "да" ',                'то нажмите клавишу "y" , если нет, то любую клавишу ');        readln(lit);      if (lit='Y') or (lit='y') then goto NAH;                               END. 
 7.3. Подпрограммы-процедуры Описание процедуры: Procedure имя (входные формальные параметры: тип; Var выходные формальные параметры: тип); описания (если они есть) begin операторы end; Пусть необходимо найти корни квадратных уравнений ax2+bx+c=0, ky2+my+d=0, sz2+tz+p=0, где коэффициенты a, b, c вводятся по запросу. количество уравнений не ограничено. результаты вычислений выводить на экран (в основную программу не возвращать), см. рис. 2.1.   Program Prim33;           label K,NAH;           Var  let:char; a,b,c:real;   procedure root(a,b,c:real); {процедура не имеет выходных параметров}             label K;             Var d,x1d,x1m,x2d,x2m:real;         Begin       if a=0 then Begin             writeln('уравнение первой степени, корень один');               x1d:=-c/b; writeln('x=',x1d); goto K; end                     else d:=b*b-4*a*c;           if d>=0 then Begin         writeln('уравнение второй степени, корни действительные');              x1d:=(-b-sqrt(d))/(2*a);              x2d:=(-b+sqrt(d))/(2*a);              writeln('x1d=',x1d,'  x2d=',x2d); goto K; end           else writeln('уравнение второй степени, корни комплексные');                x1d:=-b/(2*a);             x2d:=x1d;                    x1m:=-sqrt(-d)/(2*a);      x2m:=-x1m;             writeln('z1=',x1d,' ',x1m,' i;');             writeln('z2=',x2d,' ',x2m,' i;');     K: end;   BEGIN NAH: writeln('введите a,b,c'); readln(a,b,c); root(a,b,c);         writeln('будет еще уравнение? если "да", нажмите клавишу"Y"',                  'если "нет", нажмите любую клавишу');         read(let);     if (let='Y') or (let='y') then goto nah else goto K;   K: END. Найти x, y, z -- корни системы уравнений: Как известно из линейной алгебры ,       где    Раскрытие определителя   производится по схеме:    т.е.  в процедуре a,b,c,d - входные данные, x,y,z - результаты.     Program Prim34;       label N,K;       Type  w=array[1..3] of integer;        Var a,b,c,d:w;       x,y,z:real;   let:char;    function det(a:w;b:w;c:w):real;       Begin det:=a[1]*b[2]*c[3]+b[1]*c[2]*a[3]+c[1]*a[2]*b[3]              -c[1]*b[2]*a[3]-a[1]*c[2]*b[3]-b[1]*a[2]*c[3]; end;    procedure ur(a,b,c,d:w; Var x,y,z:real);         Var d0:real;        Begin   d0:=det(a,b,c);           if d0=0 then Begin writeln('det=0 решения нет');                        let:='0'; Exit; end  else        {EXIT - выход из процедуры}                x:=det(d,b,c)/d0;                y:=det(a,d,c)/d0;                z:=det(a,b,d)/d0;     let:='1';   end;  BEGIN  N: writeln('введите a1,b1,c1,d1'); readln(a[1],b[1],c[1],d[1]);            writeln('введите a2,b2,c2,d2'); readln(a[2],b[2],c[2],d[2]);            writeln('введите a3,b3,c3,d3'); readln(a[3],b[3],c[3],d[3]);            ur(a,b,c,d,x,y,z);        if let='0' then goto K else          writeln('                    / ',a[1],'x+',b[1],'y+',c[1],'z=',d[1]);          writeln('система  i  ',a[2],'x+',b[2],'y+',c[2],'z=',d[2]);          writeln('                  \ ',a[3],'x+',b[3],'y+',c[3],'z=',d[3]);          writeln('имеет решение: x=',x,'  y=',y,'  z=',z);    K: writeln('Будет ещё ур-е? да - "Y" , нет - любая клавиша ');      read(let);      if (let='Y') or (let='y') then goto N;    END. Имеется одномерный массив. Необходимо определить сумму положительных элементов, номер последнего отрицательного элемента, количество отрицательных элементов массива. Задача 1. Массив один и состоит из 7 элементов. Задача 2. Массивов два, размерность первого - 7 элементов, второго - 5. Задача 3. Количество массивов не ограничено, количество элементов в массивах произвольное, но не более 70.   Program Prim35;  { массив 1 и состоит из 7 элементов }          label j;          Type mas=array[1..7] of real;          Var  n,k,i,no:integer;                a:mas;                s:real;   ch:char;     procedure prmas(a:mas;n:integer; Var s:real; Var k,no:integer);             Var i:integer;         Begin   s:=0; k:=0; no:=0;             for i:=1 to n do Begin     if a[i]>=0 then  s:=s+a[i]  else Begin k:=i; no:=no+1;                        end; end; end;   BEGIN            for i:=1 to 7 do  Begin           writeln('ввести значение a[',i,']');         readln(a[i]);  end;          prmas(a,7,s,k,no);   j:     writeln('сумма положительных элементов =',s);          writeln('последний отрицательный элемент имеет N=' no);          writeln('количество отрицательных элементов =', k);           readln;   END.   Program Prim36; { массива 2, размерность первого массива 7, второго - 5}          label j;          Type mas=array[1..7] of real;          Var  k,no,y:integer;               s:real;   ch:char;    procedure prmas(n:integer; var s:real; var k,no:integer);             Var i:integer; a:mas;       Begin for i:=1 to n do Begin             writeln('введите ',i,' значение элемента массива');             readln(a[i]);  end;              s:=0; k:=0; no:=0;             for i:=1 to n do begin     if a[i]>=0 then  s:=s+a[i]  else begin k:=i; no:=no+1;                       end; end; end;   BEGIN  prmas(7,s,k,no); y:=0;   j:     writeln('сумма положительных элементов =',s);          writeln('последний отрицательный элемент имеет N=', no);          writeln('количество отрицательных элементов =', k); y:=y+1;           if  y=1 then Begin prmas(5,s,k,no); goto j; end           else readln;   END. Program Prim37; { массивы с переменными измерениями, количество    массивов не ограничено}          Type mas=array[1..70] of real;          Var  n,k,i,no,kol,r,j:integer;               a,b:mas;               s:real;   ch:char;    procedure prmas(n:integer; var s:real; var k,no:integer);            var i:integer; a:mas;         begin  for i:=1 to n do begin                writeln('введите ',i,'  значение элемента массива ', j);                 readln(a[i]); end;          s:=0; k:=0; no:=0;             for i:=1 to n do Begin     if a[i]>=0 then  s:=s+a[i]  else Begin k:=i; no:=no+1;                        end; end; end;   BEGIN          writeln('задайте количество массивов'); readln(kol);        for j:=1 to kol do Begin          writeln(' задайте размерность массива', j); readln(r);          prmas(r,s,k,no);          writeln(' сумма положительных элементов =',s);          writeln(' последний отрицательный элемент имеет N=', no);          writeln(' количество отрицательных элементов =', k); end;          readln;    END. 
 7.4. Локальные и глобальные описания объектов Мы уже знаем, что программа - блок, т.е. раздел операторов, снабженный описаниями и имеющий заголовок. Вид блока-программы:  Program имя программы (возможны опции); {опции не обязательны} Label …; {раздел описания меток} Const …; {раздел описания констант} Туре …; {раздел определения типов} Var …; {раздел описания переменных}  Function …; Procedure …; {раздел описания функций и процедур} BEGIN ... END. {раздел операторов}.  Функции и процедуры, в свою очередь, также являются блоками: Procedure имя (список входных формальных параметров); Var (список выходных формальных параметров);  Label …; Const …;  Туре …;  Var ...;  function …;  procedure …;  разделы описаний  begin ... end; {тело процедуры}  Таким образом, программа - всегда блок, в который могут быть вложены другие блоки.  Как один из вариантов, возможна следующая структура программы:            Program Prim38;           { начало блока 1}    label N,M;    Const k=5.6;  Type d=array[1..10] of integer;    Var b,c:real;  i,j:integer;  z,y:d;  function f(f,b,c:real):real;       { начало блока 2}          begin f:=1; end;           {конец блока 2}  procedure proc(f,b,c:real; Var x,y,z:real); { начало блока 3}         label K,L;         var d,w,s:real;      function fp(a,b:real):real;    { начало блока 4}                begin fp:=1; end;    {тело fp, конец блока 4}   begin x:=1; y:=1; z:=1; end;      {тело proc, конец блока 3}       BEGIN b:=1;  END.      {тело основной программы, конец блока 1} Таким образом, программа состоит из четырех блоков. Все имена меток, констант, типов, переменных, функции f и Рrос известны в блоке 1, поскольку они даны в его описании. Считается, что они описаны здесь локально.  В блоке 2 - function - описаний нет, поэтому своих собственных объектов этот блок не имеет. Формальные параметры не в счет, поскольку они служат только для описания алгоритма вычисления результата с именем f в функции f, а ячейки памяти для b, с, f здесь не выделяются. Однако в этом блоке можно использовать все объекты, которые описаны в блоке 1, так как блок 2 является составляющей частью блока 1. Иногда говорят, что имена объектов блока 1 описаны глобально для блока 2.  Аналогичная ситуация и с блоком 3 - Procedure Рrос. Для нее все объекты блока 1 являются глобальными, т.е. доступны. Кроме того, в блоке 3 имеются свои описанные здесь объекты - метки К, L, переменные d, W, 8, функция fp, которые могут быть использованы только в блоке 3 и не известны в блоках 1 и 2.  Как следствие возможно применение одинаковых имен в различных блоках (см. имя d). В блоке 1 d - массив. В блоке 3 (в Рrос) имеется свое d, которое является собственным в блоке 3 и представляет собой не массив, а ячейку памяти типа real.  8. Строковые данные8.1. Общие замечания Строка - это последовательность символов длиной 0-255. Для описания данных строкового типа используется слово string, за которым могут следовать в квадратных скобках цифры, определяющие количество символов в строке. Если цифры в квадратных скобках и сами скобки отсутствуют, то для данной ячейки памяти будет выделяться максимально возможная длина: 256 байт для хранения 265 символов. Символьные константы (которые могут храниться) имеют вид совокупности символов, заключенных в апострофы.  Пример: 'a, b, с - символы'. Примеры описаний:  Var а, b, с: string [70];  Выделяются ячейки с именами а, b, с, в каждую из которых может быть занесена совокупность символов в количестве до 70.  Например, возможны операторы: а: = 'улица Садовая';  b: = улица Чкалова, 17, хаи'; с: = г. Харьков - большой город';  возможно предварительное описание типа:  Туре a=string [70];  Var b, с: а;  
 8.2. Строковые выражения Выражения, в которых операндами служат строки, являются строковыми выражениями. Результат - строка. Опишем операции, которые можно применять при написании строковых выражений:  Операция сцепления, знак операции '+'. 'Дом'+' номер'+'43' дает результирующую строку 'Дом номер 43'.  Операции отношения: =, < >, >, <, >=, <=.  Операции отношения выполняются раньше операции сцепления, т.е. имеют более высокий приоритет.  Сравнения между строками производятся посимвольно, слева направо, до первого несовпадающего символа. Та строка считается больше, в которой первый несовпадающий символ имеет больший код по таблице кодов. Результаты сравнения - True или False.  Если строки имеют различную длину и более короткая совпадает с началом более длинной, то последняя считается большей.  При использовании оператора присваивания, если значение результата вычисления строкового выражения имеет большую длину, чем ячейка памяти, в которую записывается результат, то лишние правые символы отбрасываются. Если значение результата вычисления строкового типа короче, чем ячейка памяти, отведенная для его хранения, то результат записывается в ячейку памяти «прижатым» вправо, а лишние левые разряды заполняются пробелами.  Допускается при записи выражений строкового типа применять данные, описанные с атрибутом char. В этом случае эти данные интерпретируются как string [ 1]. К отдельным символам данного строкового типа можно обратиться по номеру этого символа в строке (аналогично индексу в массивах). В нулевом байте хранится длина строки.          Program Prim39;     var st1,st2:string[30];  BEGIN st1:='отдел № 256'; writeln(st1);        {на экране "отдел № 256"}        st2:=st1[10];  writeln(st2);                          {на экране "5"}          writeln(ord(st1[0]));                                {на экране "11"}              readln; END. Если бы в var было указано string[10], то writeln(st1), вывел бы результат "отдел № 25" 
 8.3. Стандартные процедуры и функции для обработки строк 8.3.1. Процедуры обработки строк Delete (st, Poz, N) - удаление N символов из строки с именем st, начиная с позиции Poz.  st:='река_Волга'; Delete (st, 1, 5); Результат 'Волга'.  insert (stl, st2, poz); - вставка строки stl в строку st2, начиная с позиции Poz.  st1: = 'Дом_25_'  st2: =' На_улице_живет_петух_';  insert (stl, st2, 10);  Результат: "На_улице_дом 25_живет_петух";  str (IBR, st); преобразует число IBR (типа integer, byte или Real) и помещает результат в строку st. Возможно после IBR указать ширину поля. Если ширины поля не хватает, оно автоматически расширяется до нужной величины. str (1500:6, stl); даст результат '_1500'; str (4.8е+03:10, stl); - результат '_ 4.800E+03';  str (-46854:3, stl); - результат '-46854'.  Val (st, IBR, Cod); процедура преобразует значение st в величину целочисленного или вещественного типа и помещает результат в IBR. Значение st должно содержать символьное изображение числа и не содержать символов, не присущих изображению чисел (например, пробелов перед цифрами), букв и т.п. Cod - целочисленная переменная индуцирующая ошибку. Если Cod=0, преобразование произведено без ошибки, если Cod=5, то ошибка при преобразовании - 5 символов.  Программа Program Prim 40; иллюстрирует работу вышеописанных процедур:          Program Prim40;     var st1,st2:string[30];   BEGIN st1:=' река Волга ';         delete(st1,1,5);  writeln(st1);         st1:='дом 25 '; st2:='на улице живет петух';         insert(st1,st2,10);    writeln(st2);         str(1500:6,st1); writeln(st1);         str(4.8e+03:10,st1); writeln(st1);         str(-46854:3,st1); writeln(st1);              readln;END. 
 8.3.2. Функции обработки строк Сору (st, Poz, N) выделяет из st подстроку длиной N символов, начиная с позиции Poz.  stl:='absdefg'; writeln (Сору (stl, 2, 3));  результат bсd Const (stl, st2,..., stn) выполняет сцепление строк stl... stn. Длина суммарной строки не должна превышать 255 символов.  Length (st) определяет длину строки, результат - integer.  Pos (stl, st2) обнаруживает первое появление строки stl в строке st2. Результат - целое число, определяющее номер позиции, в которой находится первый символ подстроки st1. Если st1 не содержится в строке st2, то результат равен 0. UpCase (ch) преобразует строчную букву в прописную.  Параметр и результат имеют литерный тип.  ch:=a'; UpCase (ch) имеет результат 'A'.  Program Prim 41, Prim 42, Prim 43 иллюстрируют работу вышеописанных функций.          Program Prim41;     var st1,st2:string[30];  s:char;  BEGIN st1:='отдел № 256';        writeln(copy(st1,7,5));        st2:='находится в НИИ 5';         writeln(concat(st1,st2));         writeln(length(st2));         st2:='n 256';         writeln(pos(st2,st1));         s:='a';         writeln(upcase(s)); Страницы: 1, 2, 3, 4, 5, 6, 7, 8 |