Четверг, 09.01.2025, 11:51
Главная Регистрация RSS поиск
Приветствую Вас, Гость
Меню сайта
Категории раздела
HTML [44]
Visual C++ и MFC [21]
c++ [78]
php [19]
Javascript [15]
C# [51]
загрузки [0]
XNA [10]
создание игр с помощью xna
Наш опрос
Каким языком программирования вы увлекаетесь
Всего ответов: 2420
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Реклама
Главная » Статьи » c++

Битовые поля

Битовые поля - это своеобразная структура, которая позволяет работать с отдельными битами. Синтаксис объявления битовых полей следующий:

struct [имя_структуры] {
 тип [имя_битового_поля1]: длина;
 тип [имя_битового_поля2]: длина;
 . . . . .
 тип [имя_битового_поляN]: длина; 
} [имя_объекта];

В языке С в качестве типа битовых полей обязательно нужно использовать int или unsigned. В С++ разрешено использовать кроме перечисленных выше любой тип, интерпретируемый как целый: char, bool, short, long и перечисления. Длина битового поля задается целочисленным значением, которое определяет, сколько битов необходимо выделить указанному полю. Приведем пример битовых полей:

 struct {
 unsigned name1: 1;
 unsigned name2: 3;
 unsigned name3: 5;
 } obj;
 
 obj.name1 = 1;
 obj.name3 = 30;

В приведенном примере мы создали три битовых поля. Для хранения элемента name1 выделено 1 бит, для хранения элемента name2 - 3 бита, а для хранения name3 выделено 5 бит. После объявления битовых полей в нашем примере происходит присвоение значений битовым полям. При этом удостоверьтесь, что присваиваимые значения не превышают размер поля.

Размер одного битового поля не должен превышать размер типа данного поля. То есть, если битовое поле объявлено как unsigned или int, то размер такого поля не должен превышать 32 бита.

Приведем еще один пример битовых полей. Данный пример иллюстрирует использование битовых полей для хранения колоды карт.

#include <iostream.h>
#include <iomanip.h>

//объявление битовых полей, которые описывают карту
struct Cards {
 unsigned face: 4;
 unsigned suit: 2;
};

void FillKolody(Cards *);//функция для заполнения колоды
void ShowKolody(Cards *);//функция для вывода колоды на экран

void main(){
 //создание массива, в котором хранится колода из 52 карт
 Cards koloda[52];

 //вызов функции для заполнения колоды
 FillKolody(koloda);

 //показ колоды на экран
 ShowKolody(koloda);
}

void FillKolody(Cards*koloda){
 for(int i = 0; i < 52; i++){
 //присваиваем карте значение от 0(Туз) до 12(Король)
 koloda[i].face = i%13;
 //присваиваем масть карте
 koloda[i].suit = i/13;
 }
}

void ShowKolody(Cards*koloda){
 int j = 0;
 //создаем массив значений карт
 char* arFace[] = {"Ace","2","3","4","5","6","7","8","9","10",
 "Jack","Queen","King"};
 //создаем массив значений мастей
 char* arSuit[] = {"hearts","spades","diamonds","clubs"};

 //выводим карты на экран в два столбца
 //в первом столбце карты от 0 до 25
 //во втором - от 26 до 51
 for(int i = 0; i < 26; i++){
 j = i + 26;
 cout<<"Card:"<<setw(6)<<arFace[koloda[i].face]
 <<" Suit:"<<setw(9)<<arSuit[koloda[i].suit];
 cout<<" Card:"<<setw(6)<<arFace[koloda[j].face]
 <<" Suit:"<<setw(9)<<arSuit[koloda[j].suit];
 cout<<endl;
 }
}

выведет на экран 

Card: Ace Suit: hearts Card: Ace Suit: diamonds
Card: 2 Suit: hearts Card: 2 Suit: diamonds
Card: 3 Suit: hearts Card: 3 Suit: diamonds
Card: 4 Suit: hearts Card: 4 Suit: diamonds
Card: 5 Suit: hearts Card: 5 Suit: diamonds
Card: 6 Suit: hearts Card: 6 Suit: diamonds
Card: 7 Suit: hearts Card: 7 Suit: diamonds
Card: 8 Suit: hearts Card: 8 Suit: diamonds
Card: 9 Suit: hearts Card: 9 Suit: diamonds
Card: 10 Suit: hearts Card: 10 Suit: diamonds
Card: Jack Suit: hearts Card: Jack Suit: diamonds
Card: Queen Suit: hearts Card: Queen Suit: diamonds
Card: King Suit: hearts Card: King Suit: diamonds
Card: Ace Suit: spades Card: Ace Suit: clubs
Card: 2 Suit: spades Card: 2 Suit: clubs
Card: 3 Suit: spades Card: 3 Suit: clubs
Card: 4 Suit: spades Card: 4 Suit: clubs
Card: 5 Suit: spades Card: 5 Suit: clubs
Card: 6 Suit: spades Card: 6 Suit: clubs
Card: 7 Suit: spades Card: 7 Suit: clubs
Card: 8 Suit: spades Card: 8 Suit: clubs
Card: 9 Suit: spades Card: 9 Suit: clubs
Card: 10 Suit: spades Card: 10 Suit: clubs
Card: Jack Suit: spades Card: Jack Suit: clubs
Card: Queen Suit: spades Card: Queen Suit: clubs
Card: King Suit: spades Card: King Suit: clubs

Как Вы уже поняли, ссылка на битовое поле выполняется по имени_битового_поля. Если имя поля не указано, запрошенные биты все равно выделяются, но доступ к ним невозможен. Такое поле называется неименованным битовым полем.

struct Example1 {
 unsigned n1: 6;
 unsigned : 2;
 unsigned n2: 14;
 unsigned : 2;
 unsigned n3: 5;
};

Неименованные битовые поля с шириной поля 0 задают выравнивание следующего поля по границе максимального типа элементов структуры. Например, структура битовых полей

struct Example2 {
 unsigned n1: 12;
 unsigned : 0;
 unsigned n2: 8;
};

использует неименованное поле нулевой ширины, чтобы пропустить оставшиеся биты в том элементе памяти, в котором хранится n1, и выровнять n2 по границе следующего элемента памяти. Элементом памяти выступает в данном случае 4 байта, то есть размер unsigned int. В общей сложности данная структура будет занимать в памяти 8 байт.

К битовым полям не может быть применена операция получения адреса (&) и поэтому не существует указателей на поля.

Порядок размещения битовых полей в памяти в значительной степени зависит от компилятора и аппаратного обеспечения. Не нужно пытаться экономить память с помощью битовых полей, так как это чаще всего не удается. При использовании битовых полей обычно предполагается, что память для них будет выделена в виде последовательности битовых ячеек, следовательно, структура, состоящая из трех 2-битовых полей, заняла бы 6 бит, следующих один за одним. Но так ли это на самом деле - зависит, в конце концов, от компилятора. Кроме того, адресация битов в памяти является менее рациональной, чем адресация байтов, так как компилятор должен генерировать специальные коды.

Битовые поля можно использовать для создания всевозможных масок и флагов, а также при создании двоично-упакованных объектов. 

Категория: c++ | Добавил: slava (30.05.2011)
Просмотров: 4284 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]