Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основы.doc
Скачиваний:
48
Добавлен:
07.03.2016
Размер:
3.6 Mб
Скачать

13.3. Бітові поля

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

Розглянемо приклад роботи з бітовими полями.

#include <iostream>

using namespace std;

struct bit_type

{

int i:2;

unsigned int j:6;

int :3;

unsigned int k:3;

unsigned int l:2;

} bit;

void main()

{

bit.i = 2;

bit.j = 9;

bit.k = 7;

bit.l = 2;

printf("bit=%u",bit);

}

Перше поле i має розмір 2 біти, друге поле j займає 6 бітів. Наступне поле не має назви. Поле k обмежене трьома бітами, l – обмежено двома бітами.

Наведемо розподіл пам’яті під змінну bit.

| 15 14 | 13 12 11 | 10 9 8 | 7 6 5 4 3 2 | 1 0 |

l k ----- j i

Бітове представлення змінної bit прийме наступний вигляд.

| 1 0 | 1 1 1 | 0 0 0 | 0 0 1 0 0 1 | 1 0 |

13.4. Обробка виключних ситуацій

С++ забезпечує вбудований механізм обробки помилок, який має назву обробка виключних ситуацій (exception handling). За допомогою обробки виключних ситуацій можна спростити управління на реакцію помилки під час виконання програми. Обробка виключних ситуацій в С++ організовується за допомогою трьох ключових слів: try, catch, throw. Програмний код, у якому треба відслідкувати помилку повинен знаходитись усередині блоку try. Якщо у цьому блоці буде знайдена помилка, управління автоматично передається блоку catch для її аналізу та обробки. За допомогою інструкції throw відбувається генерування помилки, при цьому управління передається блоку catch – для обробки даної помилки.

Нижче представлена основна форма інструкцій try і catch.

try

{

// блок у якому можуть відбуватись помилки

}

catch(type1 arg)

{

//блок перехвату виключної ситуації

}

catch(type2 arg)

{

//блок перехвату виключної ситуації

}

catch(typeN arg)

{

//блок перехвату виключної ситуації

}

Блок try повинен містити ту частину програми в якій необхідно відстежувати помилки. Це можуть бути як декілька операторів всередині однієї функції, так і всі оператори всередині функції main().

З блоком try може бути пов’язано більше однієї інструкції catch. Яка саме інструкція catch використовується, залежить від типу виключної ситуації. Тобто, якщо тип даних, вказаний в інструкції catch, відповідає типу виключної ситуації, виконується дана інструкція catch. Можна перехоплювати довільні типи даних, включаючи і типи створених класів.

За допомогою інструкції throw можна генерувати виключну ситуацію:

throw [вираз];

Оператор throw повинен виконуватися або всередині блоку try, або в будь-якій функції, яку цей блок викликає. Якщо ви генеруєте виключну ситуацію, для якої немає відповідної функції catch, може відбутися ненормальне завершення програми.

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

#include <iostream>

using namespace std;

void main()

{

cout<<"початок\n";

try

{

cout<<"Всередині блоку try\n";

throw 13; //генерація помилки

cout<<"Цей рядок не буде виведено";

}

catch(int i)

{

cout<<"Перехоплена помилка номер: "<<i<<"\n";

}

cout<<"кінець";

}

Результат виконання програми виглядатиме таким чином:

початок

Всередині блоку try

Перехоплена помилка номер: 13

кінець

У прикладі є блок try, який містить три оператора, та блок catch(int i), який оброблює виключну ситуацію цілого типу. Всередині блоку try будуть виконані тільки два з трьох операторів – cout і throw. Після того, як виключна ситуація збуджена, управління передається виразу catch та виконання блоку try завершується. Таким чином блок catch викликається неявно, управління виконанням програми просто передається йому. Отже, наступний за оператором throw оператор cout не буде виконаний.

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

#include <iostream>

using namespace std;

void Test(int t)

{

cout<<"Всередині функції t = "<<t<<"\n";

if(t) throw t;

}

void main()

{

cout<<"початок\n";

try

{

cout<<"Всередині блоку try\n";

Test(0);

Test(1);

Test(2);

}

catch(int i)

{

cout<<"Перехоплена помилка номер: "<<i<<"\n";

}

cout<<"кінець";

}

Результат виконання програми:

початок

Всередині блоку try

Всередині функції t = 0

Всередині функції t = 1

Перехоплена помилка номер: 1

кінець

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

#include <iostream>

using namespace std;

void Test(int t)

{

try

{

if(t) throw t;

}

catch(int i)

{

cout<<"Перехоплена помилка номер: "<<i<<"\n";

}

}

void main()

{

cout<<"початок\n";

Test(0);

Test(1);

Test(2);

cout<<"кінець";

}

Результат виконання програми:

початок

Перехоплена помилка номер: 1

Перехоплена помилка номер: 2

кінець

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

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

У наступному прикладі перехоплюються три виключні ситуації: одна для цілих чисел, одна для рядка та одна для будь-яких інших типів даних.

#include <iostream>

using namespace std;

void Test(int t)

{

try

{

if(t==0) throw t;

else if(t==1)throw "Значення рівне 1";

else throw 25.3;

}

catch(int i)

{

cout<<"Перехоплена помилка номер: "<<i<<"\n";

}

catch(char*s)

{

cout<<"Перехоплено рядок: "<<s<<"\n";

}

catch(...)

{

cout<<"Перехоплено виключення(крім цілого типу та рядку)\n";

}

}

void main()

{

cout<<"початок\n";

Test(0);

Test(1);

Test(2);

cout<<"кінець";

}

Після виконання програми побачимо наступний результат:

початок

Перехоплена помилка номер: 0

Перехоплено рядок: Значення рівне 1

Перехоплено виключення(крім цілого типу та рядку)

кінець