Оператор вираз
Будь-який вираз, який закінчується крапкою з комою, є оператором.
Виконання оператора вираз полягає в обчисленні виразу. Набуте значення виразу ніяк не використовується, тому, як правило, такі вирази викликають побічні ефекти. Помітимо, що викликати функцію, що не повертає значення можна тільки за допомогою оператора виразу. Правила обчислення виразів були сформульовані вище.
Приклади:
1++i;
Цей оператор представляє вираз, який збільшує значення змінної i на одиницю.
1a=cos(b * 5);
Цей оператор представляє вираз, що включає операції присвоєння і виклику функції.
1а(x,y);
Цей оператор представляє вираз, який складається з виклику функції.
Порожній оператор
Порожній оператор складається тільки з крапки з комою. При виконанні цього оператора нічого не відбувається. Він звичайно використовується в наступних випадках:
-
у операторах do, for, while, if в рядках, коли місце оператора не потрібне, але по синтаксису потрібен хоча б один оператор;
-
при необхідності помітити фігурну дужку.
Синтаксис мови Cі вимагає, щоб після мітки обов’язково слідував оператор. Фігурна ж дужка оператором не є. Тому, якщо треба передати управління на фігурну дужку, необхідно використовувати порожнього оператора.
Приклад:
1int main ( )
2{
3 {
4 if (...) goto а; /* перехід на дужку */
5 {
6 ...
7 }
8 а:;
9 }
10 return 0;
11}
Складовий оператор
Складовий оператор є декількома операторами і оголошеннями, укладеними у фігурні дужки:
1{
2 [оголошення]
3 ...
4 оператор; [оператор];
5 ...
6}
Зазначимо, що в кінці складового оператора крапка з комою не ставиться.
Виконання складового оператора полягає в послідовному виконанні становлячих його операторів.
Приклад:
1int main ()
2{
3 int q,b;
4 double t,d;
5 ...
6 if (...)
7 {
8 int e, g;
9 double f,q;
10 ...
11 }
12 ...
13 return 0;
14}
Змінні e, g, f, q будуть знищені після виконання складового оператора. Відзначимо, що змінна q є локальною в складовому операторі, тобто вона жодним чином не зв’язана із змінною q оголошеною на початку функції main з типом int. Відзначимо також, що вираз стоїть після return може бути укладене в круглі дужки, хоча наявність останніх необов’язкова.
Оператор if
Формат оператора:
1if (вираз) оператор-1; [else оператор-2;]
Виконання оператора if починається з обчислення виразу.
Далі виконання здійснюється по наступній схемі:
- якщо вираз істинний (тобто відмінний від 0), то виконується
оператор-1
. - якщо вираз помилковий (тобто рівний 0),то виконується
оператор-2
. - якщо вираз помилковий і відсутній
оператор-2
(у квадратні дужки вкладена необов’язкова конструкція), то виконується наступний за if оператора.
Після виконання оператора if значення передається на наступного оператора програми, якщо послідовність виконання операторів програми не буде примусово порушена використанням операторів переходу.
Приклад:
1if (i < j)
2 i++;
3else {
4 j = i-3;
5 i++;
6}
Цей приклад ілюструє також і той факт, що на місці оператор-1
, так само як і на місці оператор-2
можуть знаходитися складні конструкції.
Допускається використання вкладених операторів if. Оператор if може бути включений в конструкцію if або в конструкцію else іншого оператора if. Щоб зробити програму більш читабельної, рекомендується групувати операторів і конструкції у вкладених операторах if, використовуючи фігурні дужки. Якщо ж фігурні дужки опущені, то компілятор зв’язує кожне ключове слово else з найближчим if, для якого немає else.
Приклади:
1int main ()
2{
3 int t=2, b=7, r=3;
4 if (t > b)
5 {
6 if (b < r) r=b;
7 }
8 else
9 r=t;
10 return 0;
11}
В результаті виконання цієї програми r стане рівним 2.
Якщо ж в програмі опустити фігурні дужки, що стоять після оператора if, то програма матиме наступний вигляд:
1int main ()
2{
3 int t=2,b=7,r=3;
4 if ( a > b )
5 if ( b < з )
6 t=b;
7 else
8 r=t;
9 return 0;
10}
В цьому випадку r набуде значення рівне 3, оскільки ключове слово else відноситься до другого оператора if, який не виконується, оскільки не виконується умова, що перевіряється в першому операторі if.
Наступний фрагмент ілюструє вкладеність операторів if:
1 char ZNAK;
2 int x,y,z;
3 ...
4 if (ZNAK == '-') x = у - z;
5 else if (ZNAK == '+') x = у + z;
6 else if (ZNAK == '*') x = у * z;
7 else if (ZNAK == '/') x = у / z;
8 else
9 ...
З розгляду цього прикладу можна зробити висновок, що конструкції використовуючі вкладені оператори if, є досить громіздкими і не завжди достатньо надійними. Іншим способом організації вибору з множини різних варіантів є використання спеціального оператора вибору switch.
Оператор switch
Оператор switch призначений для організації вибору з множини різних варіантів. Формат оператора наступний:
1switch ( вираз )
2{
3 [оголошення]
4 ...
5 [ case константное-вираз1]: [ список-операторов1]
6 [ case константное-вираз2]: [ список-операторов2]
7 ...
8 [ default: [ список операторів ]]
9}
Вираз, наступний за ключовим словом switch в круглих дужках, може бути будь-яким виразом, допустимими в мові Cі, значення якого повинне бути цілим. Відзначимо, що можна використовувати явне приведення до цілого типу, проте необхідно пам’ятати про ті обмеження і рекомендації, про яких мовилося вище.
Значення цього виразу є ключовим для вибору з декількох варіантів. Тіло оператора switch складається з декількох операторів, помічених ключовим словом case з подальшим константним виразом. Слід зазначити, що використання цілого константного виразу є істотним недоліком, властивим розглянутому оператору.
Оскільки константний вираз обчислюється під час трансляції, воно не може містити змінні або виклики функцій. Звичайно як константний вираз використовуються цілі або символьні константи.
Всі константні вирази в операторі switch повинні бути унікальні. Окрім операторів, помічених ключовим словом case, можливо, але обов’язково один, фрагмент помічений ключовим словом default.
Список операторів може бути порожнім, або містити один або більш операторів. Причому в операторі switch не вимагається укладати послідовність операторів у фігурні дужки.
Відзначимо також, що в операторі switch можна використовувати свої локальні змінні, оголошення яких знаходяться перед першим ключовим словом case, проте в оголошеннях не повинна використовуватися ініціалізація.
Схема виконання оператора switch наступна:
- обчислюється вираз в круглих дужках;
- обчислені значення послідовно порівнюються з константними виразами, наступними за ключовими словами case;
- якщо один з константних виразів співпадає із значенням виразу, то управління передається на оператора, поміченого відповідним ключовим словом case;
- якщо жоден з константних виразів не рівний виразу, то управління передається на оператора, поміченого ключовим словом default, а у разі його відсутності управління передається на наступного після switch оператора.
Відзначимо цікаву особливість використання оператора switch: конструкція із словом default може бути не останньою в тілі оператора switch. Ключові слова case і default в тілі оператора switch істотні тільки при початковій перевірці, коли визначається початкова точка виконання тіла оператора switch. Всі оператори, між початковим оператором і кінцем тіла, виконуються незалежно від ключових слів, якщо тільки якийсь з операторів не передасть управління з тіла оператора switch. Таким чином, програміст повинен сам подбати про вихід з case, якщо це необхідно. Найчастіше для цього використовується оператор break.
Для того, щоб виконати одні і ті ж дії для різних значень виразу, можна помітити одного і того ж оператора декількома ключовими словами case.
Приклад:
1int i=2;
2switch (i)
3{
4 case 1: i += 2;
5 case 2: i *= 3;
6 case 0: i /= 2;
7 case 4: i -= 5;
8 default: ;
9}
Виконання оператора switch починається з оператора, поміченого case 2. Таким чином, змінна i набуває значення, рівне 6, далі виконується оператор, помічений ключовим словом case 0, а потім case 4, змінна i прийме значення 3, а потім значення -2. Оператор, помічений ключовим словом default, не змінює значення змінної.
Розглянемо раніше наведений приклад, в якому ілюструвалося використання вкладених операторів if, переписаної тепер з використанням оператора switch.
1char ZNAK;
2int x,y,z;
3switch (ZNAK)
4{
5 case '+': x = у + z; break;
6 case '-': x = у - z; break;
7 case '*': x = у * z; break;
8 case '/': x = u / z; break;
9 default : ;
10}
Використання оператора break дозволяє в необхідний момент перервати послідовність виконуваних операторів в тілі оператора switch, шляхом передачі управління оператору, наступному за switch.
Відзначимо, що в тілі оператора switch можна використовувати вкладених операторів switch, при цьому в ключових словах case можна використовувати однакові константні вирази.
Приклад:
1switch (a)
2{
3 case 1: b=c; break;
4 case 2:
5 switch (d)
6 {
7 case 0: f=s; break;
8 case 1: f=9; break;
9 case 2: f-=9; break;
10 }
11 case 3: b-=c; break;
12 ...
13}
Оператор break
Оператор break забезпечує припинення виконання самого внутрішнього з об’єднуючих його операторів switch, do, for, while. Після виконання оператора break управління передається оператору, наступному за перерваним.
Оператор for
Оператор for - це найзагальніший споCіб організації циклу. Він має наступний формат:
1for ( вираз 1 ; вираз 2 ; вираз 3 ) тіло
Вираз 1 звичайно використовується для встановлення початкового значення змінних, що управляють циклом. Вираз 2 - це вираз, що визначає умову, при якому тіло циклу виконуватиметься. Вираз 3 визначає зміну змінних, що управляють циклом після кожного виконання тіла циклу.
Схема виконання оператора for:
- Обчислюється вираз 1.
- Обчислюється вираз 2.
- Якщо значення виразу 2 відмінно від нуля (істина), виконується тіло циклу, обчислюється вираз 3 і здійснюється перехід до пункту 2, якщо вираз 2 рівний нулю (фальш), то управління передається на оператор, наступний за оператором for.
Істотне те, що перевірка умови завжди виконується на початку циклу. Це значить, що тіло циклу може жодного разу не виконатися, якщо умова виконання відразу буде помилковою.
Приклад:
1int main()
2{
3 int i,b;
4 for (i=1; i<10; i++)
5 b=i*i;
6 return 0;
7}
В даному прикладі обчислюються квадрати чисел від 1 до 9.
Деякі варіанти використання оператора for підвищують його гнучкість за рахунок можливості використання декількох змінних, що управляють циклом.
Приклад:
1int main()
2{
3 int top, bot;
4 char string[100], temp;
5 for ( top=0, bot=100 ; top < bot ; top++, bot--)
6 {
7 temp=string[top];
8 string[bot]=temp;
9 }
10 return 0;
11}
В даному прикладі, реалізовуючому запис рядка символів в зворотному порядку, для управління циклом використовуються дві змінні top і bot. Відзначимо, що на місці вираз 1 і вираз 3 тут використовуються декілька виразів, записаних через кому, і виконуваних послідовно.
Іншим варіантом використання оператора for є нескінченний цикл. Для організації такого циклу можна використовувати порожній умовний вираз, а для виходу з циклу звичайно використовують додаткову умову і оператор break.
Приклад:
1for (;;)
2{
3 ...
4 ... break;
5 ...
6}
Оскільки згідно синтаксису мови Cі оператор може бути порожнім, тіло оператора for також може бути порожнім. Така форма оператора може бути використана для організації пошуку.
Приклад:
1for (i=0; t[i]<10 ; i++) ;**
У даному прикладі змінна циклу i приймає значення номера першого елементу масиву t, значення якого більше 10.
Оператор while
Оператор циклу while називається циклом з передумовою і має наступний формат:
1while (вираз) тіло ;**
Як вираз допускається використовувати будь-який вираз мови Cі, а як тіло будь-який оператор, зокрема порожній або складовий. Схема виконання оператора while наступна:
- Обчислюється вираз.
- Якщо вираз помилковий, то виконання оператора while закінчується і виконується наступний по порядку оператор. Якщо вираз істинний, то виконується тіло оператора while.
- Процес повторюється з пункту 1.
Оператор циклу вигляду
1 for (вираз-1; вираз-2; вираз-3) тіло;
може бути замінений оператором while таким чином:
1 вираз-1;
2 while (вираз-2)
3 {
4 тіло;
5 вираз-3;
6 }
Так само як і при виконанні оператора for, в операторі while спочатку відбувається перевірка умови. Тому оператора while зручно використовувати в ситуаціях, коли тіло оператора не завжди потрібно виконувати.
Усередині операторів for і while можна використовувати локальні змінні, які повинні бути оголошені з визначенням відповідних типів.
Оператор do while
Оператор циклу do while називається оператором циклу з постумовою і використовується в тих випадках, коли необхідно виконати тіло циклу хоча б один раз. Формат оператора має наступний вигляд:
1do тіло while (вираз);
Схема виконання оператора do while:
- Виконується тіло циклу (яке може бути складовим оператором).
- Обчислюється вираз.
- Якщо вираз помилковий, то виконання оператора do while закінчується і виконується наступний по порядку оператор. Якщо вираз істинний, то виконання оператора продовжується з пункту 1.
Щоб перервати виконання циклу до того, як умова стане помилковою, можна використовувати оператора break.
Оператори while і do while можуть бути вкладеними.
Приклад:
1int i,j,k;
2...
3i=0; j=0; k=0;
4
5do {
6 i++;
7 j--;
8 while (а[k]< i) k++;
9}
10while (i<30 && j<-30);
Оператор continue
Оператор continue, як і оператор break, використовується тільки усередині операторів циклу, але на відміну від нього виконання програми продовжується не з оператора, наступного за перерваним оператором, а з початку перерваного оператора. Формат оператора наступний:
1continue;
Приклад:
1int main()
2{
3 int а,b;
4 for (a=1,b=0; a<100; b+=a,a++)
5 {
6 if (b%2) continue;
7 ... /* обробка парних сум \*/
8 }
9 return 0;
10}
Коли сума чисел від 1 до а стає непарною, оператор continue передає управління на чергову ітерацію циклу for, не виконуючи операторів обробки парних сум.
Оператор continue, як і оператор break, перериває самий внутрішній з охоплюючих його циклів.
Оператор return
Оператор return завершує виконання функції, в якій він заданий, і повертає управління в викликаючу функцію, в точку, безпосередньо наступну за викликом. Функція main передає управління операційній системі. Формат оператора:
1return [вираз];
Значення виразу, якщо воно задане, повертається в викликаючу функцію як значення функції, що викликається. Якщо вираз опущений, то значення, що повертається, не визначено. Вираз може бути укладене в круглі дужки, хоча їх наявність не обов’язкова.
Якщо в якій-небудь функції відсутній оператор return, то передача управління в викликаючу функцію відбувається після виконання останнього оператора функції, що викликається. Значення, що при цьому повертається, не визначено. Якщо функція не повинна мати значення, що повертається, то її потрібно оголошувати з типом void.
Таким чином, використання оператора return необхідне або для негайного виходу з функції, або для передачі значення, що повертається.
Приклад:
1int sum (int а, int b)
2{
3 renurn (a+b);
4}
Функція sum має два формальні параметри а і b типа int, і повертає значення типу int, про що говорить описувач, що стоїть перед ім’ям функції. Return значення, що повертається оператором, рівне сумі фактичних параметрів.
Приклад:
1void prov(int а, double b)
2{
3 double c;
4 if (a<3) return;
5 else
6 if (b>10) return;
7 else {
8 c=a+b;
9 if ((2*c-b)==11) return;
10 }
11}
В даному прикладі оператор return використовується для виходу з функції у разі виконання однієї з умов, що перевіряються.
Оператор goto
Використання оператора безумовного переходу goto в практиці програмування на мові Cі настійно не рекомендується, оскільки він утрудняє розуміння програм і можливість їх модифікацій.
Формат цього оператора наступний:
1 goto ім'я_мітки;
2 ...
3 ім'я_мітки: оператор;
Оператор goto передає управління на оператора, поміченого влучної ім’я_мітки. Помічений оператор повинен знаходитися в тій же функції, що і оператор goto, а використовувана мітка повинна бути унікальною, тобто одне ім’я_мітки не може бути використано для різних операторів програми. Ім’я_мітки - це ідентифікатор.
Будь-який оператор в складовому операторі може мати свою мітку. Використовуючи оператора goto, можна передавати управління всередину складового оператора. Але потрібно бути обережним при вході в складового оператора, що містить оголошення змінних з ініціалізацією, оскільки оголошення розташовуються перед виконуваними операторами і значення оголошених змінних при такому переході будуть не визначені.
Коментарі