5. Оператори за цикъл. Оператори за цикъл с брояч, с предусловие и с постусловие.

Дефиниция 5.1

Цикъл в един алгоритъм или програма наричаме група от една или няколко команди, които се изпълняват многократно. Циклите, организирани чрез специалните за целта оператори в Pascal се наричат явни, а тези, организирани чрез други средства на езика се наричат неявни.

Един начин за организиране на неявен цикъл бе показан в предходната точка чрез преход goto назад в програмата. Друг начин е чрез рекурсия, която ще бъде описана в седма точка.

В Pascal има четири оператора за явен цикъл. Те са:

Цикли с брояч. Това са цикли, при които предварително знаем, колко пъти ще се завъртим. При тях имаме целочислена променлива-брояч, която брои завъртанията (итерациите) на цикъла. Единият оператор е за цикъл с нарастване на брояча. Той има следния формат:

    for променлива_брояч := израз1 to израз2 do
        команда

където израз1 задава началната стойност, която приема брояча преди започването на цикъла, израз2 задава крайната стойност на брояча, при която цикълът продължава да се върти, а команда е тялото на цикъла, което се изпълнява многократно. Ако в цикъл трябва да се завъртят не една команда, а няколко, тогава се използва съставен оператор. При всяко завъртане на цикъла броячът нараства с едно. Цикълът завършва, когато стойността на брояча надхвърли стойността на израз2. Ако

    израз1 > израз2,

тогава тялото на цикъла въобще не се изпълнява, а се преминава към следващата команда след цикъла, иначе броят на завъртанията е

    израз2 - израз1 + 1.

Вътре в тялото на цикъла броячът не може да се променя.

Пример 5.1:

    i : integer;
    for i := 1 to 10 do
         writeln( i );

Този фрагмент от програма ще изведе числата от 1 до 10.

Другият оператор е за цикъл с намаляване на брояча. Той има следния формат:

    for променлива_брояч := израз1 downto израз2 do
        команда

Неговото действие е сходно с това на предходния оператор с тази разлика, че при всяко завъртане на цикъла броячът намалява с едно. Затова при него за да се завърти цикъла би трябвало

    израз1 > израз2,

иначе тялото на цикъла се прескача, а броя на завъртанията е

    израз1 - израз2 + 1.

Пример 5.2:

    i : integer;
    for i := 10 downto 1 do
         writeln( i );

Този фрагмент от програма ще изведе числата от 1 до 10 в обратен ред.

Задача 5.1: Да се състави програма, която намира средното аритметично на N реални числа.

Анализ:
Входни данни: N>0 цяло
                          a1, a2,..., aN - реални.
Изход: 

Алгоритъм

    Начало
        1. Въведи N
        2. Ако N <= 0
            Изведи Грешен брой
            Отиди към 1
        3. s  <- 0
        4. За i <- 1 до N повтаряй
            Въведи ai
             s <- s + ai
        5. s <- s / N
        6. Изведи s
    Край

Програма

program average;
    uses WinCrt;
    label 1;
    var
        a, s: real;
        i, n: integer;
    begin
1:     write('Въведете броя на числата');
        readln(n);
         if n <= 0
            then begin
                writeln('Грешен брой!');
                 goto 1             { неявен цикъл }
            end;
        s := 0;
         for i := 1 to n do
            begin
                write('Въведете ', i, '-то число:');
                readln(a);
                s := s + a;
            end;
        s := s / n;
        writeln('Средно аритметично:', s:10:4);
    end.

Цикъл с предусловие. Това е цикъл, който се изпълнява, ако е налице някакво условие (логически израз е истина). Първо се проверява условието и ако то е изпълнено, тогава се изпълнява тялото на цикъла, състоящо се от една или няколко команди. После пак се проверява условието и т.н. Цикълът завършва, когато условието повече не е изпълнено (логическият израз стане лъжа). Ако първоначално условието не е изпълнено, тялото се прескача и без то да се изпълни нито веднъж се преминава нататък в програмата. Формата на оператора за цикъл с предусловие е следния:

    while логически_израз do
        команда

където логически_израз е условието за изпълнение на цикъла, а команда е неговото тяло, което се завърта многократно. Ако в цикъл трябва да се завърти не една, а няколко команди, тогава се използва съставен оператор.

Ако при изпълнение на цикъла логическият израз остава постоянно истина (true), то цикълът няма да завърши и ще се получи безкраен цикъл. Т.е. тялото на цикъла трябва да въздейства на логическия израз, така че той в един момент да се промени от true на false и цикълът да завърши.

Пример 5.3:

    a: real;
    a := 0;
    while a <= 10 do
        a := a + 2;

Преди цикъла a е 0. При всяко завъртане на цикъла a се увеличава с 2. В края на цикъла a ще стане 12.

Задача 5.2. Да се състави програма, намираща най-големия делител на дадено цяло положително число.

Анализ
    Входни данни: N > 0 - цяло.
    Изходни данни: K - цяло.
    Знание: Най-големият делител е първото число K като се започне от N div 2 до 1, за което N mod K = 0.

Алгоритъм

    Начало
        1. Въведи N
        2. Ако N <= 0 тогава
            Изведи "Числото не е положително"
            Отиди към 1
        3.Ако N = 1 тогава 
            K <- 1
        иначе
            K <- N div 2
        4. Докато (K > 1) и (N mod K
0) повтаряй
            K <- K - 1
        5. Изведи K
    Край

Програма

program max_dividor;
    uses WinCrt;
    label 1;
    var 
        k, n: integer;
    begin
1:     write('Въведете цяло положително число:');
        readln(n);
         if n <= 0 then
            begin
                writeln('Числото не е положително !');
                 goto 1
            end;
         if n = 1
             then k := 1
             else k := n div 2;
         while (k > 1) and (n mod k <> 0) do
            k := k - 1;
        writeln('Най-голям делител на ', n , ' е числото ', k);
    end.

Цикъл с постусловие. При този цикъл условието за края му (логически израз) е след неговото тяло (повтарящите се команди). Цикълът действа по следния начин: първо се изпълнява неговото тяло, проверява се условието за край и ако то не е изпълнено (логическият израз е false), тялото отново се изпълнява и т.н. Цикълът завършва, когато се изпълни условието за край (логическият израз е true). Формата на оператора за цикъл с постусловие е следния

    repeat
        команда1;
        команда2;
        ...........
        командаN
    until логически_израз

където командите от 1 до N образуват тялото на цикъла. И тук, ако логическият израз остане винаги false, цикълът е безкраен. Основната разлика между циклите с предусловие и постусловие е, че при първия тялото може въобще да не се изпълни (ако условието първоначално е лъжа), докато при втория то се изпълнява поне веднъж.

Пример 5.4

    n : integer;
    repeat
        write('Въведете цяло положително число:');
        readln(n)
    until n > 0;

Този фрагмент от програма осигурява, че потребителят ще въведе положително число.

Задача 5.3. Да се състави програма за изчисляване на кубичен корен от x, като се използва, че ако a е някакво приближение до търсения корен, то е по-добро приближение.

Анализ
Входни данни: x - реално
Изходни данни:
b - реално.
Знание: Ще се започне от a = 1 и по горната формула ще се получи b . После a = b и отново се прилага формулата, като се получава ново още по-точно b и т.н., докато разликата между две последователни приближения стане по-малка от някаква зададена точност - много малко число.

Алгоритъм

    e = 0.0001
    Начало
        1. Въведи x
        2.
b <- 1
        3. Повтаряй
           
a <- b
           
        докато |
b - a | < e
        4. Изведи
b
    Край

Програма

program cubrt;
    uses WinCrt;
    const t = 0.0001;
    var
        x, a, b: real;

    begin
        write('x = ');
        readln(x);
        b := 1;
        repeat
            a := b;
            b := (2 * a + x / (a * a)) / 3
         until abs(b - a) < t;
        writeln('Cubrt(', x:8:3, ') =', b:10:4);
    end.

Забележка. abs е библиотечна функция за абсолютна стойност.


Съдържание


4. Оператори за логическо управление на програмата. Логически оператор. Съставен оператор (оператор-блок). Оператор за безусловен преход. Оператор за избор.


6. Деклариране на нови типове в Pascal. Тип диапазон. Масиви: едномерни, двумерни и тримерни масиви. Индексиране на масив. Обхождане на масив.