Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Паскаль Методичка.doc
Скачиваний:
4
Добавлен:
16.08.2019
Размер:
277.5 Кб
Скачать
  • Цикл с предусловием, в котором заголовок цикла содержит проверку условия повторения прохода цикла, но не изменяет параметр цикла, как это было в цикле со счетчиком.

    Цикл с предусловием отличается тем, что можно исключить возможность даже однократного исполнения оператора прохода цикла.

    While {условие выполнения оператора прохода цикла} do

    {оператор прохода цикла };

    Обычно цикл состоит из нескольких операторов Паскаля, которые объединяются при помощи операторных скобок.

    Например, требуется вычислить таблицу значений функции

    Y = (x2 – 0,3) 2 – tg (x2-0,3) при x=[0,2;1,2] с шагом Δx = 0,2

    Заметим, что можно вести промежуточную переменную yy = x2-0,3;

    тогда, с учетом отсутствия функции tg в Паскале, получим Y = yy 2 – sin yy / cos yy.

    Блок-схема алгоритма приведена на рис. 2.1

    начало

    x = 0,2

    x ≤1,2 нет

    д а

    yy = x2-0,3

    Y = yy 2 – sin yy / cos yy

    Вывод x, y

    X = x+0,2

    конец

    Рис 2.1

    Текст программы имеет вид

    Program cikle1;

    Uses CRT;

    Var x,yy,y: real;

    begin CLRSCR; {очистка экрана}

    x := 0.2;

    while x <= 1.2 do begin

    yy := sqr(x) – 0.3;

    y := yy*yy – sin(yy)/cos(yy);

    writenl (‘x = ‘, x:5:2,’y = ‘:5,y:6:3);

    x := x+0.2;

    end;

    end.

    1. Цикл с постусловием, который в заголовке не содержит указания на параметр цикла, а в конце прохода помещается оператор проверки условия выхода из цикла.

    Цикл с постусловием может использоваться как для итерационных циклов, так и для циклов с регулярно изменяющимся параметром цикла.

    Repeat

    {операторы цикла}

    until {условие выхода из цикла};

    Рассмотрим тот же пример: блок-схема будет отличаться тем, что блок проверки условия переместится ниже изменения параметра цикла и изменит знак неравенства

    X > 1,2

    Текст программы имеет вид

    Program cikle1;

    Uses CRT;

    Var x,yy,y: real;

    begin CLRSCR; {очистка экрана}

    x := 0.2;

    Repeat

    yy := sqr(x) – 0.3;

    y := yy*yy – sin(yy)/cos(yy);

    writenl (‘x = ‘, x:5:2,’y = ‘:5,y:6:3);

    x := x+0.2;

    until x > 1.2;

    end.

    Заметим, что в данном цикле не требуются операторные скобки.

    Для вычисления функций двух и более переменных используются вложенные циклы, которые должны соответствовать определенным правилам.

    Главное:

    • вложенные циклы управляются разными параметрами цикла;

    • внутренний цикл начинается позже внешнего цикла и заканчивается раньше.

    Рассмотрим пример функции двух переменных. Требуется вычислить значения функции для всех сочетаний аргументов

    при x = [-1;1] ; Δx = 0,5; y = [3;5]; Δy = 1; a = 2,3

    Сначала оценим особенности алгоритма.

    Можно ввести промежуточную переменную zp = xy.

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

    Nx = (1-(-1))/0,5+1 = 5 и Ny = (5-3))/1+1 = 3

    выбираем внешний цикл с повторением 3 раза, т.е. по переменной у.

    Блок- схема приведена на рис.2.1.

    Начало

    y = 3; a = 2,3

    i от 1 до 3

    вывод у

    x = -1

    j от 1до 5

    zp = xy

    вывод x, z

    x = x+0,5

    y = y+1

    возврат

    Рис 2.1

    Текст программы:

    Program Prim1;

    Uses CRT;

    Const a = 2.3;

    Var j,i: integer; x,y,zp,z: real;

    BEGIN Clrscr; y:= 3;

    for i:=1 to 3 do begin

    writeln (‘ y =’, y:5:1);

    x:= -1;

    for j:=1 to 5 do begin

    zp := x*y;

    z := zp – 1/(1.3 + cos(a+zp);

    writeln (‘ x =’, x:5:1, ‘ z =’, z:7:4);

    x := x + 0.5;

    end;

    y := y + 1;

    end;

    END.

    2.2. Структуры разветвляющихся алгоритмов

    Как известно, разветвляющиеся алгоритмы используются для алгоритмов, требующих проверки каких-то условий и различных действий, в зависимости от результатов этих проверок.

    Существует три структуры разветвляющихся алгоритмов:

    1. разветвление с общим продолжением, когда после выполнения тех или иных операторов (ветвей), выполняется оператор, следующий за условным оператором;

    2. разветвление с раздельным окончанием, когда одна из ветвей приводит к окончанию алгоритма;

    3. разветвление с «пустой ветвью», когда при проверке получен результат «ложь», то выполняется следующий оператор.

    При разветвлении на три ветви можно пользоваться вложением условных операторов или тремя краткими условными операторами.

    Например, вычислим значение функции

    для a = 0,42; n = 1,64; m = 0,5 sin n.

    для разветвления используем более сложную структуру с последовательной проверкой условий (см. рис.2.2)

    Текст программы:

    Program Prim2;

    Uses CRT;

    Const a = 0.42;

    Var m,n,z: real;

    BEGIN Clrscr; n:= 1.64;

    m := 0.5*sin(n);

    if m < 0.53 then z := sqrt (m*m + n)

    else if m = 0.53 then z := a*m*m + n*n

    else z := a*m*m + cos(a*m*m);

    writeln (‘ m =’, m:7:3, ‘ z =’, z:7:4);

    END.

    Начало

    a=0,42 n =1,64

    m = 0,5 sin n

    m < 0,53

    да

    z =

    m = 0,53

    да

    z = am2 – n2 z = am2 + cos am2

    Вывод x, Y

    Конец

    Рис. 2.2

    Рассмотрим использование в данной программе трех условных операторов. Тогда фрагменты блок- схемы и программы будут иметь вид (см. рис.2.3)

    Практическая часть.

    Переписать программу вычисления таблицы значений той же функции для m = [0,5;0,6] с шагом Δm = 0,01. Самостоятельно написать программу вычисления функций, заданных на дом, и получить результаты.

    . . .

    m < 0,53 z = if m < 0.53 then z := sqrt (m*m + n);

    m = 0,53 z = am2 – n2 if m = 0.53 then z := a*m*m + n*n;

    m > 0,53 am2 + cos am2 if m > 0.53 then z := a*m*m + cos(a*m*m);

    . . .

    рис. 2.3

    2.3. Обработка индексированных переменных

    Массив – это набор элементов, имеющих одно имя и упорядоченный одним или несколькими отрезками натурального ряда, называемыми индексами. Количество индексов, используемых для указания элемента, называется размерностью массива. Индексы записываются в Паскале в квадратных скобках после имени и разделяются запятыми (если их несколько).

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

    X: ARRAY [1..4] OF Real;

    где начальное и конечное значения индекса разделяются двумя точками.

    Для двумерного массива (матрицы) S(3,4) декларация может иметь вид

    S: ARRAY [1..3, 1..4] OF integer;

    Рассмотрим пример: задан двумерный массив Р(2,6), требуется элементы первой строки разделить на соответствующие элементы второй строки. (Массив произвольный, первая строка не должна содержать нули).

    Блок-схема очевидна, программа имеет вид.

    Программа имеет вид:

    Program Matrix1;

    Uses CRT;

    Var i, j: integer;

    p: Array [1..2,1..6] of integer;

    begin CLRSCR; {очистка экрана}

    Write (‘Vvedite znacheniya p[i,j]: ’);

    {ввод массива по строкам} for i :=1 to 2 do

    for j :=1 to 6 do read (s[i,j]);

    {обработка массива} for j := 1 to 6 do

    p[1,j] := p[1,j] / p[2,j] ;

    Writeln (‘ noviy massiv p’);

    for i:=1 to 2 do begin

    for j:=1 to 6 do write (p[i,j]:6); writeln;

    end;

    end.

    Часто встречаются задачи поиска суммы или произведения элементов массива.

    Например, требуется вычислить сумму элементов одномерного массива чисел, формируемых датчиком случайных чисел.

    Датчик случайных чисел от 0 до целой величины N – это стандартная функция

    RANDOM (N). Если нужно сформировать массив чисел, содержащий также отрицательные элементы, то рекомендуется использовать выражение вида

    RANDOM (N) – N/2.

    Заметим, что необходимо вывести на экран полученный массив. Пусть элементы массива принимают значения от -10 до 10.

    Б лок- схема программы представлена на рис.2.4.

    Начало Program sluchaj;

    sum = 0 var k : integer; sum : real;

    d: array [1..7] of real;

    k от 1 до 7 begin sum := 0;

    dk = random(20)-10 for k := 1 to 7 do begin

    d[k] := random(20)-10;

    вывод dk writeln (‘k = ’,k, ‘ d[k]=’,d[k]:5:2);

    sum = sum + dk sum := sum + d[k];

    end;

    вывод sum writeln(‘summa = , sum:5:2);

    end.

    конец

    Рис. 2.4

    Псевдографика в Турбо-Паскале

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

    Например, для построения таблицы и графика функции у = x2 для x=[0,1;1] с шагом h=0,1, можно написать программу, приведенную ниже. При этом необходимо провести предварительное масштабирование переменной и преобразование ее в форму целого числа.

    Для удобства построения графика сначала обычно выводят на экран таблицу значений функции, а затем определяют коэффициент масштабирования, который согласует изображение с длиной строки экрана – 70 позиций.

    В данной программе для очистки экрана используется функция Clrscr,входящая в ибилиотеку Crt. Подключение ибилиотеки производится директивой Uses.

    program prim3;

    Uses Crt;

    var k,i:integer; x:real;

    Y:Array [1..10] of real;

    begin

    Clrscr;

    x:=0.1;

    {рисуем таблицу}

    for i:=1 to 21 do write('-'); writeln;

    writeln ('|','x':5,'|':6,'y':5,'|':6);

    write('|');

    for i:=1 to 21 do write('-'); writeln('|');

    for i:=1 to 10 do begin

    y[i]:=sqr(x);

    writeln('|',x:6:2,'|':5,y[i]:6:3,'|':5);

    x:=x+0.1;

    end;

    {рисуем график функции}

    for i:=1 to 50 do write('-');

    writeln;

    for i:=1 to 10 do begin

    k:=round(50*y[i]);

    writeln('|','*':k);

    end;

    end.

    Результаты на экране будут иметь вид:

    |---------------------|

    | x | y |

    |---------------------|

    | 0.10 | 0.010 |

    | 0.20 | 0.040 |

    | 0.30 | 0.090 |

    | 0.40 | 0.160 |

    | 0.50 | 0.250 |

    | 0.60 | 0.360 |

    | 0.70 | 0.490 |

    | 0.80 | 0.640 |

    | 0.90 | 0.810 |

    | 1.00 | 1.000 |

    ------------------------------------------------------------

    |*

    | *

    | *

    | *

    | *

    | *

    | *

    | *

    | *

    *

    Масштабирование графиков

    Пусть f(xi)- значение функции на i-ом шаге цикла вычислений. Воспользуемся линейным масштабированием f(xi) , тогда

    0  B+A f(xi)  70

    для всех x = [x0 , xk ]

    где x0 – начальное значение,

    xk - конечное значение.

    Для определения значений коэффициентов следует определить значения fmin и fmax на отрезке [x0 , xk ]. Пусть требуется построить график в позициях [T1 , T2 ] строки экрана (или бумаги). Тогда имеем

     T1 = B+A fmin

     T2 = B+A fmax

    Откуда получим

    A = (T2 - T1) /( fmax - fmin )

    B = T1 - A fmin

    При T1 = 0 и T2 = 70 соответственно имеем

    A = 70 /( fmax - fmin )

    B = - A fmin

    Если требуется построить графики двух функций в одних осях координат, то необходимо определить общие масштабные коэффициенты. Кроме того, требуется постоянно определять последовательность размещения символов, относящихся к разным функциям (например, '@' и '#'). В случае, когда значения функций различаются друг от друга менее, чем на одну позицию, т.е.

    F1 (xi) – F2 (xi)  1/A

    их можно изобразить другим символом (например, '+')

    2.4. Обработка символьной информации на Турбо-Паскале

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

    Символьные переменные могут быть двух видов:

    1. один символ описывается как переменная типа CHAR. Например,

    var ch_1, x : char;

    begin ch_1 := ‘A’; x := ‘7’;

    Каждому символу соответствует один байт, содержащий ASCII -код, который может быть представлен целым положительным числом. Причем, коды от 0 до 127 соответствуют стандарту ASCII, а вторая половина кодов (от 128 до 255) – это национальные алфавиты.

    Определить номер кода символа можно стандартной функцией (см. РМ8). Например,

    ORD(‘A’) = 65

    ORD(‘a’) = 97.

    Обратная функция CHR(65) = ‘A’ , имя функции можно заменить символом

    # 65 = ‘A’,

    здесь целочисленный параметр функции должен иметь тип BYTE.

    Переменные типа char относятся к порядковому типу (упорядоченному), поэтому к ним применимы функции

    - предшественник PRED(‘b’) = ‘a’,

    - преемник SUCC(‘A’) = ‘B‘.

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

    For ch_1 := ‘a’ to ‘z’ do

    Writeln (‘код литеры ‘, ch_1, ‘ равен ’, ord(ch_1));

    2) строковые переменные описываются как переменные типа STRING. Например,

    var s : string; {переменная с максимальной длиной 256 символов}

    v : string(10); { переменная с максимальной длиной 10 символов }

    text: Array [5] of s; {массив строк типа S}

    s := ‘ Поздравляю с новым годом!’;

    v := ‘Я ищу грибы!’; {v = ‘Я ищу гриб’ – только 10 символов}

    можно обращаться к элементам строки, как в массивах. Например,

    v[4] := ‘д’;

    Writeln (v);

    получится

    Я иду гриб

    Есть другие функции для строковых переменных.

    Функция слияния (конкатенация) имеет вид

    CONCAT (str1, str2);

    Например, из слов «конь» и «як» сделать слово «коньяк». Программа имеет вид

    Program Alla;

    Var A, B, C : string [20];

    Begin

    A := ‘конь’; B := ‘як’;

    C := concat (A,B);

    Writeln ( C ) ;

    End.

    Функция измерения длины строки.

    LENGTH(str)

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

    LENGTH(s) = 26;

    Разберем обработку строковых переменных на примере. Пусть требуется в строке текста (до 50 символов) подсчитать число вхождений буквы «е». Строка:

    «некуда пойти, нечего делать, ничего не хочется»

    Для упрощения программы не используем в строке заглавные буквы.

    Блок-схема очевидна: требуется один цикл для перебора букв в строке и сравнения их с искомой. Тогда программа имеет вид.

    Program stroka;

    Var C,i : integer; {счетчик вхождений}

    A: string[50];

    Begin A := ‘некуда пойти, нечего делать, ничего не хочется’ ;

    C := 0;

    For I := 1 to length(A) do

    if A[i] = ‘е’ then C := C + 1;

    writeln (‘ c = ’, c);

    end.

    В ряде случаев требуется определить число вхождений не одного символа, а сочетания символов. Например, в той же строке требуется определить число вхождений сочетания букв «не». В этом случае необходимо использовать сложное условие, которое легче всего реализовать при помощи логической функции «И» (AND), тогда условный оператор будет иметь вид

    if (A[i] = ‘н’) AND (A[i+1] = ‘е’) then C := C + 1;

    2.5. Вспомогательные алгоритмы: процедуры

    Подпрограмма – это отдельно оформленный вспомогательный алгоритм, позволяющий реализовать типовой участок основного алгоритма, в котором одинаковым образом обрабатываются переменные с разными именами.

    Подпрограммы бывают двух видов:

    • процедуры, которые могут выполнять определенные действия и преобразовывать (или не преобразовывать) несколько переменных, называемых параметрами процедуры;

    • функции, которые формируют одно значение переменной, соответствующей имени функции, в зависимости от значений параметров (аргументов).

    Каждая подпрограмма должна быть описана отдельной программной единицей (с отдельной блок-схемой). Описание располагается до начала основной программы.

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

    Например, требуется найти максимальный элемент для двух массивов А(8) и В(8). Для этого требуется ввести функцию MAXELEM, параметром которой является имя массива, а результатом – искомый элемент. Тогда программа имеет вид (блок- схемы основной программы и функции очевидны). Считаем, что элементы массива – это случайные числа вещественного типа.

    Program PrimFun;

    Const N=8;

    Var A,B: array [1..N] of real;

    i,j: integer; z: real;

    function MAXELEM(x: array [1..N] of real): real;

    begin

    Maxelem := x[1];

    For j:=1 to N do If Maxelem <= x[j] then Maxelem := x[j];

    End; {конец функции}

    BEGIN

    For i := 1 to N do begin {цикл заполнения массивов}

    A[i] := random(20); B[i] := random (30) – 15 ;

    End;

    For i := 1 to N do write (A[i]:7:2); writeln;

    Z := MAXELEM(A); Writeln (‘A max = ’,Z:5:2);

    For i := 1 to N do write (B[i]:7:2); writeln;

    Z := MAXELEM(B); Writeln (‘B max = ’,Z:5:2);

    END.

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

    Описание процедуры аналогично описанию функции. Заголовок имеет вид

    procedure {имя процедуры}({список неизменяемых формальных параметров};

    var {список изменяемых формальных параметров});

    Обращение к процедуре (вызов) имеет вид:

    {имя процедуры}({список фактических параметров});

    где фактические параметры в списке разделяются запятыми.

    Например, требуется найти максимальные элементы массивов, рассмотренных ранее, и их индексы.

    Тогда функция MAXELEM заменяется на процедуру с тем же именем, и программа имеет вид.

    Program PrimFun;

    Const N=8;

    Var A,B: array [1..N] of real;

    i, j, im: integer; z: real;

    procedure MAXELEM(x: array [1..N] of real, var M: real; mi: integer);

    Begin

    M := x[1]; mi := 1;

    For j:=1 to N do

    If M := x[j] then

    begin M := x[j]; mi := j; end;

    End; {конец функции}

    BEGIN

    For i := 1 to N do begin {цикл заполнения массивов}

    A[i] := random(20); B[i] := random (30) – 15 ;

    End;

    For i := 1 to N do write (A[i]:7:2); writeln;

    MAXELEM(A,z,im); Writeln (‘A max = ’,Z:5:2,‘ index =’,im);

    For i := 1 to N do write (B[i]:7:2); writeln;

    MAXELEM(B,z,im); Writeln (‘B max = ’,Z:5:2, ‘ index =’,im);

    END.

    39