logo search
ООП для Заоч / Пинчук Лозовская Программир на С

Void main()

{ bool t, f;

t = (200>45); // значення виразу "істина"

f = (200<45); // значення виразу "неправда"

printf("t is %d \n", t);

printf("f is %d \n", f);

}

Протокол роботи програми:

t is 1

f is 0

Логічні операції в мові С відповідають операціям математичної логіки: ! - заперечення (інверсія), || - операція логічного додавання (або диз'юнкція або "логічне АБО"), && - операція логічного множення (або кон’юнкція або "логічне І"). Нижче наведено таблицю істинності для цих операцій.

x

y

!x

x || y

x && y

0

0

1

0

0

0

1

1

1

0

1

0

0

1

0

1

1

0

1

1

Особливістю логічної операції || (АБО) є таке: якщо при обчисленні результату операції (вираз1) || (вираз2) - значення лівого операнду (вираз1) буде true, то значення другого операнда на результат операції вже не впливає, він завжди буде дорівнювати true. У цьому випадку другий операнд і не обчислюється. Аналогічна ситуація має місце і для операції && (логічне І): якщо лівий операнд дорівнює значенню false, то результат буде false незалежно від значення правого операнду.

Побітові логічні операції

Побітові логічні операції виконуються над кожною парою відповідних бітів цілочислових операндів. Список побітових операцій:

~ - заперечення (інверсія);

& - операція І;

| - операція АБО;

^ - заперечення рівнозначності (не еквівалентність);

<< - зсув бінарного коду вліво;

>> - зсув бінарного коду вправо.

Операція "~" є унарною, решта операцій - бінарні. Побітові операції виконуються для операндів будь-якого цілочислового типу. Операнди дійсного типу не допускаються.

Таблиці істинності для операції ~, &, ^, | такі ж самі, як і для відповідних логічних операцій. Тільки в цьому випадку порівнюються не значення виразів, а значення кожної відповідної пари бітів (двійкових розрядів) значень операндів.

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

Розглянемо приклад застосування побітових операцій. Щоб установити значення старшого розряду однобайтової змінної ch рівним одиниці зручно використати побітову операцію АБО. При виконанні наступного оператора

ch = ch | 128;

старший біт символьної змінної ch буде встановлено в одиницю.

Якщо ж потрібно встановити в нуль старший біт символьної змінної, то доцільно використати побітову операцію "&":

ch = ch & 127;

Результатом операції зсуву << є зсув всіх бітів лівого операнду на кількість позицій (двійкових розрядів), що задає вираз праворуч, вліво. Результатом операції >> є зсув бітів вправо. Двійкові позиції, що звільняються, заповнюються нулями. Формат запису для цих операцій виглядає так:

змінна << кількість_позицій ,

змінна >> кількість_позицій .

Нехай, наприклад двійкове подання числа А є 00001001, тоді після виконання наступних операцій будемо мати:

B=A<<3; // B = 01001000

C=A>>3; // C = 00000001

При використанні операцій зсуву відбувається втрата старших або молодших двійкових розрядів.

Операції присвоювання

Група операцій присвоювання складається з операціі простого присвоювання і набору операцій комбінованого присвоювання. Операція простого присвоювання із символом "=" формує (обчислює) значення правого операнду й привласнює його об'єкту, що відповідає лівому операнду. При виконанні операції комбінованого присвоювання спочатку виконується відповідна бінарна операція, а потім отриманий результат привласнюється об'єкту, що відповідає лівому операнду. У мові С/С++ визначені наступні операції комбінованого присвоювання:

+= - додати й привласнити;

-= - відняти й привласнити;

*= - помножити й привласнити;

/= - розділити й привласнити;

%= - розділити націль й привласнити;

>>= - виконати зсув бітів вправо й привласнити;

<<= - виконати зсув бітів вліво й привласнити;

&= - виконати побітову кон’юнкцію й привласнити;

|= - виконати побітову диз’юнкцію й привласнити;

^= - виконати побітову операцію заперечення рівнозначності й привласнити.

На відміну від інших мов програмування у мові С/С++ присвоювання є не оператор, а операція. Операція простого присвоєння "=", також як і решта операцій комбінованого присвоєння є бінарними операціями, результатом їх виконання є посилання на лівий операнд. Лівим операндом може бути вираз виду Lvalue, правим - вираз Rvalue або Lvalue.

У виразі (z=x+y)>0 спочатку обчислюється величина x + y, яка далі привласнюється змінній z, отримане значення z порівнюється з нулем.

Допускається запис ланцюжка операцій присвоєння:

x=y=z=a/d;

У такому виразі операції присвоювання виконуються справа наліво.

Використання операцій комбінованого присвоювання дозволяє записувати оператори більш лаконічно. Так, замість оператора

k = k+3; (1)

можна записати оператор

k+=3; (2)

Крім стилістичного моменту тут важливим є те, що комбіноване присвоєння виконується швидше, ніж відповідна бінарна операція й наступне присвоєння. Тут, щоправда, слід зазначити, що при завданні відповідного режиму оптимізації для компілятора, при виконанні операторів (1) і (2) буде побудована та ж сама послідовність інструкцій. Якщо це так, тоді вибір із двох зазначених вище операторів - усього лише справа стилю запису програми й особистих переваг програміста.

Операції простого та комбінованого присвоювання відносяться до операцій-процедур, бо вони змінюють значення лівого операнду.

Інші операції

До групи інших операцій відносяться операції:

&x - одержати адресу змінної x, унарна операція, символом операції є "&"; *p - операція повертає посилання на об'єкт із адресою p, унарна операція, символом операції є "*";

::x - доступ до змінної x, яку визначено в глобальному просторі імен, унарна операція, символом операції є "::";

S.x - повертається посилання на компонент x структурованого об'єкта S, бінарна операція, символом операції є ".";

S.*p - повертається посилання на компонент структурованого об'єкта S з відносною адресою p, бінарна операція, символом операції є ".*";

pS->x - повертається посилання на компонент x того об'єкта, який має адресу pS, бінарна операція, символом операції є "->";

pS->*p - повертається посилання на компонент з відносною адресою p для об’єкта з адресою pS, бінарна операція, символом операції є "->*";

L ?x : y - повертається посилання на x, якщо значенням логічного виразу L є "істина" або посиланні на y, якщо ні, операція має три операнди, символом операції є "?:";

sizeof(x) або sizeof x - операція повертає розмір об'єкта x у байтах, унарна операція, символом операції є "sizeof";

sizeof(тип) - повертається розмір об'єкта зазначеного типу, унарна операція, символом операції є " sizeof ";

(тип)x - перетворити значення x до зазначеного типу, унарна операція, символом операції є "(тип)";

(тип*)p - перетворити значення покажчика p до зазначеного типу, унарна операція, символом операції є "(тип*)";

new тип - створити об'єкт зазначеного типу, повертається адреса створеного об'єкту, повертається адреса створеного масиву, унарна операція, символом операції є "new";

new тип [розмір] - створити масив об'єктів зазначеного типу, повертається адреса створеного масиву, унарна операція, символом операції є "new[]";

delete p - знищити об'єкт з адресою p, це унарна операція яка нічого не повертає, символом операції є "delete";

delete[] p - знищити масив об'єктів з адресою p, унарна операція, символом операції є "delete[]";

A,B - виконати послідовно вирази A, B, повернути значення B;

M[k] - операція індексування, вибрати елемент масиву M з номером k, бінарна операція з символом "[]";

ім'я(параметри) - викликати функцію із зазначеними ім'ям та параметрами, бінарна операція з символом "()".

Розглянемо деякі з перерахованих вище операцій. Про інші мова йтиме у наступних розділах посібника.

Операція вибору - єдина операція, що має три операнди. Вона записується у такий спосіб:

s ? x : y

Тут x,y - вирази, s - логічний вираз. Якщо s має значення true, результатом виконання операції буде x, інакше - y. У тому випадку, коли x,y є виразами виду Lvalue, то операція ?: повертає посилання на x або на y. Наведемо два приклади застосування операції вибору.

absa = (a>0) ? a : -a;

У цьому рядку виконується обчислення абсолютної величини числа a.

min = (x<y)?x:y;

Тут визначається мінімальне з двох значень.

За допомогою операції вибору можна дуже лаконічно запрограмувати, наприклад, таку операцію: із двох змінних x і y тій, що має менше значення, привласнити значення 0:

(x<y)?x:y = 0;

Наведемо ще один приклад використання тернарної операції вибору. У наступному фрагменті програми підраховується кількість елементів у числовому масиві x, які не є кратними 3. Результат заноситься в змінну K.

int i, K = 0;

for (i=0;i<N;i++) K+= x[i]%3 ? 1:0 ;

Операція sizeof має дві форми: sizeof(вираз) і sizeof (тип). Результатом цієї операції є розмір відповідного об'єкта в байтах. У першому випадку вираз, зазначений в дужках, не обчислюється, замість цього визначається його тип і, потім, розмір об'єкта, що відповідає цьому типу.

Операція із символом "," (кома) має найнижчий пріоритет із всіх операцій. Виконується вона зліва направо, її значенням є значення правого операнда. У виразі

вираз1, вираз2

спочатку виконується вираз1 потім вираз2. Значення вираз2 і буде результатом операції. Прикладом використання цієї операції є такий оператор циклу:

for (i=1,sum=0; i<=10; i++ ) sum+=exp(i);

Пара виразів i=1, sum=0 виконує ініціалізацію змінної циклу i та обнуляє початкове значення sum для підсумовування.

Порядок обчислення виразу, пріоритети і асоціативність операцій

При написанні програми важливо уявляти собі, у якому порядку обчислюється той чи інший вираз. Порядок при обчисленні виразу визначається:

- круглими дужками: у першу чергу обчислюється підвираз у внутрішній парі дужок;

- пріоритетами операцій: спочатку виконуються операції з більш високим пріоритетом;

- асоціативністю операцій: операції з однаковим пріоритетом виконуються або зліва направо, або справа наліво, залежно від асоціативності операції.

Виклик функції має більш високий пріоритет, ніж будь-яка інша операція. Символи операцій, їх категорії пріоритетів і асоціативності наведені нижче в таблиці. Найвищим вважається пріоритет 1, а найнижчим - пріоритет 16.

Таблиця 1. Категорії пріоритетів і асоціативність операцій

Пріоритет

О п е р а ц і я

Асоціативність

1

() [] -> :: .

2

! ~ -- ++ & * (тип) sizeof new delete

3

.* ->*

4

* / %

5

+ -

6

<< >>

7

< <= > >=

8

== !=

9

&

10

^

11

|

12

&&

13

| |

14

?:

15

= *= /= %= += - =

&= ^= |= <<= >>=

16

,

Послідовність обчислення виразу можна задати примусово, розставивши належним чином дужки.

Переповнення при виконанні операції

При виході результату виконання цілочисельної операції за межі інтервалу відповідного типу (при переповненні розрядної сітки) переривання роботи програми стандартними засобами не відбувається. При виконанні операцій з дійсними типами вихід значення за межі припустимого інтервалу генерує сигнал виключної ситуації, у відповідь на яку операційна система завершує програму аварійно, з виведенням відповідного повідомлення.