Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
консплекС++1к 2013.doc
Скачиваний:
0
Добавлен:
31.12.2019
Размер:
667.14 Кб
Скачать

Лекція 3.Оператори керування роботою програми.

План лекції (4 години)

  1. Оператори

  2. Побітові оператори

  3. Інкрементування та декрементування

  4. Арифметичні оператори

  5. Оператор присвоювання

  6. Оператори порівняння та логічні оператори

  7. Умовний оператор

  8. Оператор кома.

  9. Приорітети виконання операторів

  10. Оператори (ствердження).

Оператори.

Оператор - це лексема, яка поєднує деякі обчислення, коли застосовується до змінної чи до іншого об’єкту у виразі. C++ надає великий набір операторів не лише арифметичних та логічних, але й для побітових маніпуляцій, доступу до компонентів структур та об’єднань та операцій з вказівниками. Також С++ надає додаткові оператори для доступу до елементів класу та їх об’єктів, а також механізм для перевантаження операторів. Перевантаження дає змогу перевизначити дію довільного стандартного оператора, коли застосовується до об’єкту даного класу.

У мовах С/С++ є оператори, яких немає в інших мовах програмування. До них відносяться побітові оператори, оператори інкрементування та декрементування, умовний оператор, оператор кома, а також оператори комбінованого присвоювання.

Побітові оператори

Побітові оператори звертаютья до змінних як до наборів бітів, а не як до чисел. Ці оператори застосовуються у тих випадках, коли потрібно отримати доступ до окремих бітів даних, наприклад при виведенні графічних зображень на екран. Побітові оператори можуть виконувати дії тільки з цілочисловими значеннями. На відміну від логічних операторів з їх допомогою порівнюються не два числа цілком, а окремі їх біти. Існує три основних побітових операторів: ТА (&), АБО (|) та виключаюче АБО (^). Сюди можна віднести унарний оператор побітового заперечення (~), який інвертує значення бітів числа.

ТА(&)

Оператор & записує в біт результату одиницю тільки тоді, коли обидва порівнюваних біти дорівнюють 1, як показано у наступній таблиці:

Біт 0

Біт 1

Результат

0

0

0

0

1

0

1

0

0

1

1

1

Цей оператор часто застосовують для маскування окремих бітів числа.

АБО(|)

Оператор | записує в біт результату одиницю тоді, коли принаймні один з порівнюваних бітів дорівнює 1, як показано у наступній таблиці:

Біт 0

Біт 1

Результат

0

0

0

0

1

1

1

0

1

1

1

1

Цей оператор застосовують для встановлення окремих бітів числа.

виключаюче АБО(^)

Оператор ^ записує у біт результату одиницю тоді, коли порівнювані біти відрізняються один від одного, як показано у наступній таблиці:

Біт 0

Біт 1

Результат

0

0

0

0

1

1

1

0

1

1

1

0

Цей оператор часто застосовується при виведенні зображень на екран. коли потрібно накладати один на одного кілька графічних шарів.

Оператори зсуву

Мови С/С++ містять два оператори зсуву: вліво << та зсув вправо >>. Перший зсуває бітове представлення цілочислової змінної, вказаної зліва від оператора, вліво на кількість бітів, вказану праворуч від оператора. При цьому звільнені молодші біти заповнюються нулями, а відповідна кількість старших бітів втрачається .

Зсув беззнакового числа на одну позицію вліво з заповненням молодшого розряду нулем еквівалентне множенню числа на 2, як показано у наступному прикладі:

unsigned int value1=.65;//молодший байт: 0100 0001

value1<<=1;// молодший байт: 1000 1010

при друкуванні<<value1;//виведеться 130

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

unsigned int value1=.10;//молодший байт: 0000 0001

value1>>=1;// молодший байт0000 0101

при друкуванні<<value1;//виведеться 5

Інкрементування та декрементування

Операції збільшення чи зменшення значення змінної на 1 настільки часто зустрічається у програмах, що розробники мови С передбачили для таких випадків спеціальні оператори інкрементування (++) та декрементування (--). Ці оператори можна застосовувати тільки до змінних, але не до констант.

Так, замість наступного рядка value1+1; можна записати рядок value1++; або ++value1;

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

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

Наприклад, при постфіксному інкрементуванні і++ спочатку повертається значення змінної, після чого воно збільшується на одиницю. З іншого боку, оператор префіксного інкрементування ++і вказує, що спочатку потрібно збільшити значення змінної, а потім повернути його як результат. Розглянемо приклади. нехай є наступні змінні:

int i=3,j,k=0;

Тепер проаналізуємо, як зміняться значення змінних у наступних виразах (передбачається, що вони виконуються не послідовно, а кожна окремо):

k=++I;//i=4,k=4

k=i++;//i=4,k=3

k=--i;//i=2,k=2

k=i--;//i=2,k=3

i=j=k--;//i=0,j=0,k=-1

Арифметичні оператори

У мовах С/С++ є всі стандартні арифметичні оператори, серед яких оператори додавання (+), віднімання (-), ділення (/) та ділення по модулю (%). Перші чотири зрозумілі і не вимагають пояснення. Можливо, потрібно зупинитися на операції ділення по модулю:

int a=3,b=8,c=0,d;

d=b%a;//результат: 2

d=a%b;// результат: 3

d=b%c;// результат: повідомлення про помилку

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

Оператор присвоювання

Присвоювання у С/С++ відрізняється від подібних операцій в інших мовах програмування тим, що, як і інші оператои С/С++, оператор присвоювання не повинен записуватися в окремому рядку і може входити до складніших виразів. Як результат оператор повертає значення, надане лівому операнду. Наприклад, наступний вираз буде коректним:

value1=8*(value2=5);

У даному випадку спочатку змінній value2 надається значення 5, після чого це значення помножиться на 8 і результат 40 запишеться у змінну value1.

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

value1=value2=value3=0;

Другий прийом часто можна зустріти в умовних виразах циклу while, як у наступному прикладі:

while((c=getchar())!=EOF){ …}

Спочатку змінній с надається значення, яке повертає функція getchar(), після чого виконується перевірка значення змінної на рівність константі EOF. Цикл завершиться при виявленні кінця файлу. Використання круглих дужок потрібно через те, що оператор присвоювання має менший приорітет, ніж більшість інших операторів, серед яких оператор нерівності. Без круглих дужок даний рядок буде сприйматися наступним чином:

c=(getchar()!=EOF)

Тобто змінній с буде надане значення 1 (true) кожного разу, коли функція getchar()повертає значення, що відрізняється від признака кінця файлу.

Комбіновані оператори присвоювання

Набір операторів присвоювання у мовах С/С++ значно більший, ніж у інших мовах програмування. Різноманітні комбіновані оператори присвоювання дають змогу найбільше стиснути програмний код. У наступних рядках показані деякі вирази присвоювання, стандартні для більшості мов високого рівня:

irow_index=irow_index+irow_increment;

ddepth= ddepth-dl_fathom;

fcalculate_tax= fcalculate_*1.07;

fyards= fyards/ifeet_convert;

Тепер подивимось, як ці ж вирази будуть записані на С/С++:

irow_index+= irow_increment:

ddepth-= dl_fathom;

fcalculate_tax/= ifeet_convert;

Якщо уважно розглянути ці приклади, тоді легко можна зрозуміти синтаксис комбінованих операторів присвоювання. Якщо у лівій та правій частинах виразу зустрічається одна й та ж змінна, тоді можна видалити посилання на неї з правої частини, а відповідний оператор об’єднати з оператором присвоювання. Комбінований оператор вказує, що над змінними з лівої та правої частин виразу потрібно виконати операцію, вказану перед знаком рівності. а результат знову присвоїти змінній з лівої частини виразу. Всі комбіновані оператори присвоювання названі у таблиці.

Оператор

Операція

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

::

Розширення області видимості

-

::

Доступ до члена класу за іменем класу

-

[ ]

Доступ до елемента масиву

Зліва направо

( )

Виклик функції

Зліва направо

( )

Приведення об’єкта до іншого типу

-

.

Прямий доступ до члена класу (через об’єкт)

Зліва направо

->

Непрямий доступ до члена класу (через вказівник на об’єкт)

Зліва направо

++

Постфіксний інкремент

-

--

Постфіксний декремент

-

new

Динамічне створення об’єкта

-

delete

Динамічне знищення об’єкта

-

delete [ ]

Динамічне знищення масиву

-

++

Префіксний інкремент

-

--

Префікс ний декремент

-

*

Розкриття вказівника

-

&

Отримання адреси

-

+

Унарний плюс

-

-

Унарний мінус

-

!

Логічне НЕ

-

~

Побітове НЕ

-

sizeof

Отримання вимірності виразу у байтах

-

sizeof ()

Отримання вимірності типу даних у байтах

-

typeid ()

Отримання інформації про тип операнда

-

( тип даних)

Приведення типу

Зправа наліво

const_cast

Приведення типу

-

dynamic_cast

Приведення типу

-

reinterpret_cast

Приведення типу

-

static_cast

Приведення типу

-

.*

Прямий доступ до вказівника на член класу (через об’єкт)

Зліва направо

->*

Непрямий доступ до вказівника на член класу (через вказівник на об’єкт)

Зліва направо

*

Множення

Зліва направо

/

Ділення

Зліва направо

%

Ділення по модулю

Зліва направо

+

Додавання

Зліва направо

-

Віднімання

Зліва направо

<<

Зсув вліво

Зліва направо

>>

Зсув вправо

Зліва направо

<

Менше

Зліва направо

>

Більше

Зліва направо

<=

Менше або дорівнює

Зліва направо

>=

Більше або дорівнює

Зліва направо

==

Дорівнює

Зліва направо

!=

Не дорівнює

Зліва направо

&

Побітове ТА

Зліва направо

^

Побітове виключаючи АБО

Зліва направо

|

Побітове АБО

Зліва направо

&&

Логічне ТА

Зліва направо

||

Логічне АБО

Зліва направо

?:

Умовний вираз

-

=

Просте присвоювання

Зправа наліво

*=

Присвоювання з множенням

Зправа наліво

/=

Присвоювання з діленням

Зправа наліво

%=

Присвоювання з діленням по модулю

Зправа наліво

+=

Присвоювання з додаванням

Зправа наліво

-=

Присвоювання з відніманням

Зправа наліво

<<=

Присвоювання зі зсувом вліво

Зправа наліво

>>=

Присвоювання зі зсувом вправо

Зправа наліво

&=

Присвоювання з побітовим ТА

Зправа наліво

|=

Присвоювання з побітовим АБО

Зправа наліво

^=

Присвоювання з побітовим виключаючим АБО

Зправа наліво

,

Кома

Зліва направо

Оператори порівняння та логічні оператори

Оператори порівняння призначені для перевірки рівності чи нерівності порівнюваних операндів. Всі вони повертають true у випадку встановлення істинності виразу та false у протилежному випадку. Нижче показаний список операторів порівняння, що застосовуються у мовах С та С++.

Оператор

Перевірка , яка виконується

==

Дорівнює ( не плутати з оператором присвоювання)

!=

Не дорівнює

>

Більше

<

Менше

<=

Менше або дорівнює

>=

Більше або дорівнює

Логічні оператори ТА (&&), АБО ( ||) та НЕ ( !) повертають значення true або false залежно від логічного відношення між операндами. Так, оператор && повертає true, коли істинні ( не дорівнюють нулю) обидва його аргументи. Оператор || повертає false тільки тоді, коли хибні (дорівнюють нулю) обидва його аргументи. Оператор ! інвертує значення власного операнда з false на true та навпаки.

Потрібно пам’ятати, що при порівнянні значень типу float та double відмінність навіть у останній цифрі після коми буде сприйнята як нерівність.

Умовний оператор

Оператор ?: часто застосовується в різних умовних конструкціях. Він має наступний синтаксис:

Умова ? вираз1 : вираз2;

Якщо умова дорівнює true, тоді виконується вираз1, у протилежному випадку – вираз2.

Оператор кома.

Надає можливість послідовно виконати два вирази, записані у одному рядку. Синтаксис оператора такий:

лівий_вираз, правий вираз

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

Послідовність виконання різних дій у виразі визначається компілятором. Внаслідок цього можуть виходити невірні результати, якщо не враховувався порядок розгляду виразу компілятором. Побічні ефекти також можуть виникати при неправильному використанні простого та комбінованого операторів присвоювання. тому важливим є встановлення чітких приорітетів при виконанні операторів та порядку обчислення операндів. Наприклад, операція логічного АБО (&&)завжди виконується зліва направо:

while((c=getchar())!=EOF)&& (c!=’\n’))

Оператор && наперед визначає, що спочатку буде виконаний вираз зліва від нього, тобто змінній с буде присвоєне значення, що повертає функція getchar(), і тільки потім це значення перевіряється на рівність символу нового рядка.

У таблиці перелічені всі оператори мов С та С++ у порядку зменшення їх приорітетів (для компілятора Microsoft Visual C++) і вказується напрям обчислення операндів (асоціативність): зліва чи зправа наліво.

Оператори (ствердження).

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

Блоки. Складений оператор (блок) - це список операторів, записаних у {}. Синтаксично блок розглядається як один оператор і впливає на сферу дії ідентифікаторів. Ідентифікатор, оголошений всередині блоку, має сферу дії, починаючи з точки оголошення і закінчуючи "}". Блоки вкладаються один в один.

Помічені оператори. Оператор можна мітити наступними способами:

1. ідентифікатор-мітки : оператор;

Ідентифікатор-мітки служить призначенням для безумовного оператора goto, він має власний простір дії імені та має сферу дії функції. Наприклад,

goto m; …m: аlpha=10;

2. case константний-вираз : оператор; default : оператор

Оператори, помічені як case та default, застосовуються тільки у switch.

Оператор виразу. Довільний вираз з наступною ";" створює оператор виразу: <вираз>;

Компілятор C++ виконує оператор, обчислюючи вираз. Більшість операторів виразу - це оператори надання чи виклику функцій. Спеціальний випадок - це порожній оператор, що складається тільки з «;» Він нічого не виконує і застосовується тоді, коли синтаксис мови вимагає оператора, але програмі нічого не потрібно виконувати.

Оператор вибору. Оператор вибору вибирає альтернативні варіанти, перевіряючи визначене значення. Існує 2 типи операторів вибору: if...else та switch.

Оператор if - має вигляд: if (умовний вираз) оператор1; <else оператор2>

Умовний вираз у круглих дужках має скалярний тип. Якщо вираз обчислюється у 0 (чи null для вказівника), тоді він має значення false; інакше true. Якщо немає частини else, а вираз true, тоді оператор1 виконується; інакше він ігнорується. Якщо else оператор2 присутні і вираз true, тоді оператор1 виконується; інакше він ігнорується, а оператор2 виконується. Всі вирази типу цілі чи вказівник можуть застосовуватися як логічний тип в умовних виразах. Вирази відношення (a>b) (якщо вірно) обчислюються в int 1 (true) якщо (a>b), і в int 0 (false), якщо (a<=b). Вказівник перетворюється так, що він завжди може правильно порівнюватися з константним виразом, що обчислюється в 0. Тобто тест для null вказівника може записуватися if (!ptr)... чи if (ptr==0)....

Оператор2 та оператор1 теж можуть бути операторами if, надаючи можливість виконувати серію перевірок, вкладених на довільну глибину. else відноситься до найближчого if, тому потрібно використовувати {}:if (x == 1) {if (y == 1)x=1; }else x= 2;

Оператор switch - має формат: switch (sw-вираз)

сase с1: {оператор1; break;}

сase с2: {оператор2; break;}

default:оператор3;

Він передає керування на один з кількох помічених операторів залежно від значення sw-вираз, яке має цілий тип. Довільний оператор у case сХ (серед яких і порожній оператор) можна помічати однією чи кількома мітками:

case cХ де кожна константа вибору cХ - це константний вираз з унікальним цілим значенням всередині оператора switch. Недопустимо дублювати константи вибору у одному операторі switch. Допускаєтся одна мітка default: default:оператор3. Після обчислення sw-вираз порівнюється з одним із cХ, якщо відповідність знайдена, тоді керування передається на оператор cХ з відповідною міткою. Якщо відповідність не знайдена і є мітка default, тоді керування передається на оператор3. Якщо відповідність не знайдена і мітки default немає, тоді ні один з операторів не виконується. На виконання програми не впливає наявність case та міток default. Керування просто передається, пропускаючи мітки, до наступного оператора чи перемикача. Щоб перервати виконання групи операторів для відповідного вибору, застосовується break.

Оператори ітерації (цикли).

Оператори ітерації дають змогу циклічно виконувати набір операторів. У компіляторі C++ є 3 форми ітерації: while, do, for.

Оператор while. Формат оператора: while (умовний-вираз) оператор;

() потрібні. Оператор циклу оператор виконуватиметься доти, доки умовний-вираз не стане рівним 0 (false). Спочатку обчислюється та перевіряється умовний-вираз, якщо його значення не 0 (true), тоді оператор виконується; якщо немає операторів переходу, які виходять з циклу, умовний-вираз обчислюється знову. Цей цикл повторюється доти, доки умовний-вираз не стане рівним 0. Як і в операторі if, вираз типу вказівник можна порівняти з null вказівником while (ptr)... еквівалентно while (ptr != NULL)...

Цикл while зручно використовувати для сканування рядків та інших структур даних, завершених 0: char str[10]= “Visual”; char *ptr=&str[0]; int count = 0; // ...

while (*ptr++); count++;

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

Оператор do while. Формат оператора do { оператор }while (умовний-вираз);

Оператор оператор виконується доти, доки умовний-вираз не набуде значення 0 (false). Відмінність від оператора while у тому, що умовний-вираз обчислюється після, а не перед кожним виконанням оператора циклу. Таким чином, оператор виконається принаймні 1 раз. До умовного виразу застосовуються ті ж правила, що і для while.

Оператор for. Формат оператора:

for (<вираз-ініціювання>;<умовний-вираз>; <вираз-збільшення>)оператор;

Вираз-ініціювання може бути виразом чи оголошенням. Послідовність наступна:

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

2. Умовний вираз обчислюється за правилами циклу while. Якщо вираз не 0 (true), тоді оператор циклу виконується. Якщо умовний вираз порожній, це аналогічно while (1), тобто завжди true. Якщо значення умовного виразу 0 (false), тоді цикл for завершується.

3. Вираз збільшення змінює один чи більше лічильників.

4. Обислюється вираз <оператор> (можливо порожній), а керування передається на крок 2. Якщо довільний з необов’язкових елементів порожній, тоді ставитться ";":

for(;;) { }. Сфера дії оголошеного ідентифікатора розширюється до кінця оператора for. Наприклад for (int i=1; i<j; ++i) { if (i...)... } // вірно

Оператори переходу.

Оператор переходу виконує безумовне передавання керування. Існує 4 оператори переходу: break, continue, goto, return.

Оператор break. Синтаксис break;

Оператор break можна застосовувати тільки всередині оператора ітерації (while, do, for) та switch для їх завершення. Оскільки ітерації та switch можна перемішувати та вкладати на довільну глибину, тому впевніться, що break виконує вихід для потрібного циклу чи switch. break закінчує найближчий оператор ітерації чи switch.

Оператор continue. Синтаксис continue;

Застосовується тільки всередині оператора ітерації; він передає керування на умовний вираз для циклів while та do і на умовний вираз у циклі for. Для вкладених циклів оператор continue діє для найближчої ітерації.

Оператор goto. Синтаксис goto мітка;

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

Оператор return. Якщо тип поверненого значення функції не void, тоді тіло функції містить принаймні один оператор return: return вираз_що_повертається; де вираз_що_повертається повинен мати тип type чи тип, який перетворюється на type наданням. Значення виразу, що повертається є повернене функцією rvalue, При досягненні оператора return функція завершується; якщо return не зустрівся, тоді виконання закінчується при досягненні останньої } тіла функції. Якщо повертається тип - void, тоді оператор return можна записати { ... return; }

РОЗДІЛ 2. ТИПИ ДАНИХ У МОВІ С++