- •Поля бітів у структурах.
- •2.1.1. Розміщення полів бітів у пам'яті
- •2.1.2. Доступ до полів бітів. Ініціалізація полів бітів. Недопустимі дії
- •2.1.3. Приклади програм з використанням бітових полів
- •2.2. Програмна реалізація об’єднань
- •2.2.1. Оголошення об'єднання
- •2.2.2. Ініціалізація об'єднання
- •2.2.3. Вказівник на об'єднання
- •2.3. Звертання до елементів (полів) об'єднання
- •2.4. Розміщення об'єднань у пам'яті
- •2.5. Приклади програм з використанням об'єднань
- •3. Контрольне завдання
- •4. Зміст звіту
- •Варіанти індивідуальних завдань
Лабораторна робота № 4
МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
Національний університет “Львівська політехніка”
Поля бітів у структурах.
ПРОГРАМНА РЕАЛІЗАЦІЯ ОБ’ЄДНАНЬ
Інструкція
до лабораторної роботи № 4
з курсу “Проблемно-орієнтоване програмування”
для студентів базового напрямку 6.050101
"Комп’ютерні науки"
ЗАТВЕРДЖЕНО
на засіданні кафедри
Системи автоматизованого проектування
Протокол № 1 від 11.09.2014 р.
ЛЬВІВ 2014
1. МЕТА РОБОТИ
Мета роботи - навчитися використовувати поля бутів у структурах для роботи з бітовими константами, а також реалізовувати логічні структури на основі об’єднань.
2. ТЕОРЕТИЧНІ ВІДОМОСТІ
2.1. Поля бітів у структурах
Мови С/C++ допускають використання в структурах особливого типу полів - так званих полів бітів. Це група сусідніх (двійкових) розрядів (бітів), розташованих в області пам'яті змінної цілого типу. Використання даних полів уможливлює доступ до окремих бітів більших об'єктів, наприклад байтів або слів. Використання полів бітів доцільно в тому випадку, коли для зберігання інформації в структурі даних досить декількох бітів.
Загальний синтаксис опису бітового поля:
тип [ім'я]: ширина;
Розглянемо кожне поле опису.
Поле "тип"
В C++ для визначення вмісту бітового поля дозволено використовувати будь-який тип, який інтерпретується як цілий: char, short, іnt, long (з модифікаторами sіgned або unsіgned), перерахування. У полях типу sіgnedкрайній лівий біт є знаковим. Наприклад, при оголошенні поля типуsіgnedшириною в один біт (наприклад, sіgned а: 1;) воно буде здатне зберігати тільки -1 або 0, так як будь-яка ненульова величина буде сприйматися як (-1).
Поле "ім'я"
Посилання на бітове поле виконуються по імені, зазначеному в полі "ім'я". Якщо ім'я в даному полі не зазначено, то запитана кількість біт буде відведена, але доступ до них буде неможливий.
Дозволяється опис поля бітів без імені і з шириною рівною 0 - у цьому випадку наступне поле буде починатися із границі цілого (див. далі).
Поле "ширина"
Кожному полю виділяється точно стільки бітів, скільки зазначено в полі "ширина". Даний вираз повинен мати невід’ємне ціле значення. Це значення не може перевищувати числа розрядів, необхідного для подання значення типу, зазначеного в поле "тип".
Отже, оголошення структури, що містить поля бітів має такий вигляд:
structім'я_ структури
{ тип [ ім'я1 ] : ширина;
тип [ ім'я2 ] : ширина;
тип [ім'яN] : ширина;
};
Розглянемо приклади оголошення бітових полів. Оголошення шаблона:
struct bіtfldl
{ іnta:2;
unsіgnedb:3;
};
Оголошення шаблона й визначення змінних:
struct bіtfld2
{ sіgned a:l;
unsіgned b:2;
іnt :4;
іnt c:4;
:0;
unsіgned d:10;
} bfl, bf2;
2.1.1. Розміщення полів бітів у пам'яті
Поля бітів розташовуються в машинному слові справа наліво, тобто в напрямку від молодших розрядів до старшого в черговості їхнього оголошення. Якщо звернутися до загального оголошення структури з полями бітів описаному вище, то розміщення полів у пам'яті можна представити в такий спосіб:
Старші Розряди машинних слів Молодші |
ім'яNім'я2 ім'я1 |
Якщо загальна ширина полів бітів у структурі не кратна восьми (тобто деякі бітові поля будуть не повністю займати байт), то відповідна кількість бітів даного байта буде вільною.
Наприклад:
struct EXAMPLE
{ unsіgned a:3;
іnt b:2;
};
Даний запис забезпечить наступне розміщення полів у пам'яті:
Розряди байта | |||||||
| |||||||
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Не використов. |
b |
a |
Як згадувалося вище, бітове поле не може виходити за рамки оголошеного для нього типу, тому воно завжди впаковується або в місце, що залишилося в машинному слові від розміщення попереднього бітового поля, або, якщо попередній елемент структури не був бітовим полем або бітів у поточному осередку недостатньо, у наступний байт машинного слова.
Наприклад:
struct EXAMPLE
{ іnt a:7;
b:5;
unsіgned іnt c:10;
};
Очевидно, що бітові поля, оголошені в даному прикладі, не поміщаються в рамках одного машинного слова. У цьому випадку буде наступний розподіл пам'яті:
Машинне слово m+1 |
Машинне слово m | |||
15 . . . 10 |
9 . . . 0 |
15 . . . 12 |
11 . . . 7 |
6 . . . 0 |
Нe використ. |
с |
Нe використ. |
b |
a |
|
10 бітів> 4 бітів |
|
|
Для примусового вирівнювання поля бітів на границю цілого - необхідно перед вирівнюваним полем оголосити поле без імені з шириною, рівною нулю:
struct EXAMPLE
{ іnt а:3;
unsіgned іnt b:2;
іnt :0; // Наступне поле вирівняти на границю цілого!
іnt c:6;
};
У цьому випадку оголошені поля бітів можуть поміститися в одному машинному слові, але оголошення " int:0;" пропонує розмістити поле "c" на границі машинного слова, що слідує за тим, де розташовані поля "a" і "b".
Машинне слово m+1 |
Машинне слово m | ||||||
15 ... 6 |
5 ... 0 |
15 ... 5 |
4 |
3 |
2 |
1 |
0 |
Нe використ. |
c |
Нe використ. |
b |
а | |||
|
6 бітів < 11 бітів |
|
Кількість бітів буде відведено, але доступу до них не буде. Наприклад:
struct EXAMPLE { int a:2;
unsigned int b:2;
int :3;
int c:l;
};
Розряди байта | ||||||||
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 | |
с |
До цих бітів доступу немає |
b |
a |