Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
knrc (1).pdf
Скачиваний:
16
Добавлен:
12.02.2016
Размер:
926 Кб
Скачать
☆

Роздiл 3

Керування потоком

Вирази керування потоком якоїсь мови вказують на послiдовнiсть в якiй виконуються обчислювальнi дiї. Ми вже ознайомилися з бiльшiстю звичайних конструкцiй керування потоком у попереднiх прикладах; у цьому роздiлi ми поповнимо набiр i будемо точнiшими стосовно того, що обговорювалося ранiше.

3.1Вирази та блоки

Вираз на зразок x = 0 або i++ або printf(...) стають твердженням, якщо за ними слiдує крапка з комою, як от

x = 0; i++;

printf(...);

У C, крапка з комою позначає закiнченням твердження, а не роздiлювач, як це прийнято в таких мовах як Pascal.

Фiгурнi дужки { та } використовуються для згуртовування оголошень i тверджень разом у складне твердження, або блок, тож вони синтаксично еквiвалентнi єдиному твердженню. Яскравим прикладом цього є фiгурнi дужки, що оточують твердження всерединi функцiй, так само як дужки пiсля if, else, while або for. (Змiннi може бути оголошено всерединi будь-якого блоку; ми обговоримо це в Роздiлi 4.) Крапка з комою не потрiбнi пiсля правої фiгурної дужки, яка завершує блок.

3.2If-else

Вирази if-else застосовуються для вираження ймовiрних рiшень. Формально синтаксис наступний:

if (вираз)

61

62

РОЗДIЛ 3. КЕРУВАННЯ ПОТОКОМ

твердження1 else

твердження2

де else-частина не є обов’язковою. Вираз обчислюється; якщо вiн iстинний (тобто вираз не має нульового значення), виконується твердження1. Якщо хибний (вираз має нульове значення) i наявна else-частина, тодi виконується твердження2, натомiсть.

Оскiльки if просто перевiряє числове значення виразу, це дозволяє використовувати певнi скорочення в кодуваннi. Найочевиднiшим є написання

if (вираз)

замiсть

if (вираз != 0)

Iнодi це виглядає природньо i зрозумiло, а iнколи занадто зашифровано. Оскiльки else-частина у виразi if-else не обов’язкова, то може виникнути не-

однозначнiсть, коли якийсь else пропущено у гнiздованiй послiдовностi виразiв if. Це вирiшується шляхом пов’язування else iз найближчим попереднiм if, що не має вiдповiдного else. Так, наприклад, у

if (n > 0)

if (a > b) z = a;

else

z = b;

else вiдповiдає if, що знаходиться всерединi, що ми також пiдкреслили вiдступами. Якщо це не те, чого ви хотiли, тодi потрiбно використати фiгурнi дужки, щоб змусити до вiдповiдної належностi:

if (n > 0) { if (a > b)

z = a;

}

else

z = b;

Неоднозначнiсть особливо небезпечна в ситуацiях як наступна:

3.3. ELSE IF

63

if (n >

0)

for (i = 0; i < n; i++)

 

if (s[i] > 0) {

 

printf("...");

 

return i;

 

}

else

/* ПОМИЛКА */

printf("error -- n is negative\n");

Не зважаючи на те, що вiдступи нiби недвозначно вказують на те, що саме ви маєте на увазi, компiлятор не збагне цього i пов’яже else з if всерединi. Таку помилку буває дуже важко знайти пiзнiше, тому у випадку гнiздованих if краще вживати фiгурнi дужки.

До речi, звернiть увагу на крапки з комою пiсля z = a

if (a > b) z = a;

else

z = b;

Вони там тому, що граматично за if слiдує твердження, а стверджувальнi вирази на зразок a = z; завжди мають закiнчуватися крапкою з комою.

3.3Else if

Конструкцiя

if (вираз) твердження

else if (вираз) твердження

else if (вираз) твердження

else if (вираз) твердження

else твердження

зустрiчаються настiльки часто, що вимагають невеликого обговорення. Ця форма ifвиразiв є найбiльш узагальненим способом написання виразiв вибору з-помiж багатьох напрямкiв. Умови (вираз) розглядаються по-черзi, якщо якась з умов справджується,

64

РОЗДIЛ 3. КЕРУВАННЯ ПОТОКОМ

твердження, пов’язанi з цiєю умовою буде виконано, i це покладе кiнець усьому ланцюжку. Звичайно, що код кожного виразу може складатися як з одного рядка, так i з групи, включеної у фiгурнi дужки.

Останнє else має справу з випадками, що не збiглися з жодною умовою вище, це те що виконуватиметься поза вибором, якщо всi умови не справдилися. Iнодi може не бути жодної дiї яку потрiбно би було виконати поза вибором, у таких випадках кiнцеве

else твердження

можна не включати, або його можна використати для вловлювання помилок на кшталтнеможливих умов.

Для iлюстрацiї вибору у трьох напрямках, ось функцiя двiйчастого пошуку, яка виявляє чи певне значення x з’являється у масивi v. Елементи v мають знаходитись у порядку зростання. Функцiя повертає позицiю (число мiж 0 та n-1), якщо значення x знайдено у v, i -1 — якщо нi.

Двiйчастий пошук спочатку порiвнює (введене) значення x iз середнiм елементом масиву v. Якщо x менший за значення посерединi, тодi пошук зосереджується на нижнiй частинi списку, якщо навпаки — бiльший, то на верхнiй. В обох випадках, наступним кроком буде порiвняння x iз середнiм елементом вибраної половини. Цей процес подiлу вiдрiзкiв на два продовжується доти, доки значення не буде знайдено, або дiапазон виявиться порожнiм.

/* binsearch: знаходить x серед v[0] <= v[1] <= ... <= v[n-1] */ int binsearch(int x, int v[], int n)

{

int low, high, mid;

low = 0; high = n - 1;

while (low <= high) { mid = (low+high) / 2; if (x < v[mid])

high = mid - 1; else if (x > v[mid])

low = mid + 1;

else

/* знайдено збiг */

return mid;

}

 

return -1;

/* збiгу немає */

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]