20.6. Bit Fields

C++ provides the ability to specify the number of bits in which an integral type or enum type member of a class or a structure is stored. Such a member is referred to as a bit field. Bit fields enable better memory utilization by storing data in the minimum number of bits required. Bit field members must be declared as an integral or enum type.


Image Performance Tip 20.1

Bit fields help conserve storage.


Consider the following structure definition:

struct BitCard
{
   unsigned face : 4;
   unsigned suit : 2;
   unsigned color : 1;
}; // end struct BitCard

The definition contains three unsigned bit fields—face, suit and color—used to represent a card from a deck of 52 cards. A bit field is declared by following an integral type or enum type member with a colon (:) and an integer constant representing the width of the bit field (i.e., the number of bits in which the member is stored). The width must be an integer constant.

The preceding structure definition indicates that member face is stored in four bits, member suit in 2 bits and member color in one bit. The number of bits is based on the desired range of values for each structure member. Member face stores values between 0 (Ace) and 12 (King)—four bits can store a value between 0 and 15. Member suit stores values between 0 and 3 (0 = Diamonds, 1 = Hearts, 2 = Clubs, 3 = Spades)—two bits can store a value between 0 and 3. Finally, member color stores either 0 (Red) or 1 (Black)—one bit can store either 0 or 1.

The program in Figs. 20.1420.16 creates array deck containing BitCard structures (line 25 of Fig. 20.14). The constructor inserts the 52 cards in the deck array, and function deal prints the 52 cards. Notice that bit fields are accessed exactly as any other structure member is (lines 14–16 and 25–30 of Fig. 20.15). The member color is included as a means of indicating the card color.


 1   // Fig. 20.14: DeckOfCards.h
 2   // Definition of class DeckOfCards that
 3   // represents a deck of playing cards.
 4   #include <array>
 5
 6   // BitCard structure definition with bit fields
 7   struct BitCard                                 
 8   {                                              
 9      unsigned face : 4; // 4 bits; 0-15          
10      unsigned suit : 2; // 2 bits; 0-3           
11      unsigned color : 1; // 1 bit; 0-1           
12   }; // end struct BitCard                       
13
14   // DeckOfCards class definition
15   class DeckOfCards
16   {
17   public:
18      static const int faces = 13;
19      static const int colors = 2; // black and red
20      static const int numberOfCards = 52;
21
22      DeckOfCards(); // constructor initializes deck
23      void deal() const; // deals cards in deck
24   private:
25      std::array< BitCard, numberOfCards > deck; // represents deck of cards
26   }; // end class DeckOfCards


Fig. 20.14. Definition of class DeckOfCards that represents a deck of playing cards.


 1   // Fig. 20.15: DeckOfCards.cpp
 2   // Member-function definitions for class DeckOfCards that simulates
 3   // the shuffling and dealing of a deck of playing cards.
 4   #include <iostream>
 5   #include <iomanip>
 6   #include "DeckOfCards.h" // DeckOfCards class definition
 7   using namespace std;
 8
 9   // no-argument DeckOfCards constructor intializes deck
10   DeckOfCards::DeckOfCards()
11   {
12      for ( size_t i = 0; i < deck.size(); ++i )
13      {
14         deck[ i ].face = i % faces; // faces in order               
15         deck[ i ].suit = i / faces; // suits in order               
16         deck[ i ].color = i / ( faces * colors ); // colors in order
17      } // end for
18   } // end no-argument DeckOfCards constructor
19
20   // deal cards in deck
21   void DeckOfCards::deal() const
22   {
23      for ( size_t k1 = 0, k2 = k1 + deck.size() / 2;
24         k1 < deck.size() / 2 - 1; ++k1, ++k2 )
25         cout << "Card:" << setw( 3 ) << deck[ k1 ].face
26            << "  Suit:" << setw( 2 ) << deck[ k1 ].suit
27            << "  Color:" << setw( 2 ) << deck[ k1 ].color
28            << "   " << "Card:" << setw( 3 ) << deck[ k2 ].face
29            << "  Suit:" << setw( 2 ) << deck[ k2 ].suit
30            << "  Color:" << setw( 2 ) << deck[ k2 ].color << endl;
31   } // end function deal


Fig. 20.15. Member-function definitions for class DeckOfCards.


 1   // Fig. 20.16: fig20_16.cpp
 2   // Card shuffling and dealing program.
 3   #include "DeckOfCards.h" // DeckOfCards class definition
 4
 5   int main()
 6   {
 7      DeckOfCards deckOfCards; // create DeckOfCards object
 8      deckOfCards.deal(); // deal the cards in the deck
 9   } // end main


Card:  0  Suit: 0  Color: 0   Card:  0  Suit: 2  Color: 1
Card:  1  Suit: 0  Color: 0   Card:  1  Suit: 2  Color: 1
Card:  2  Suit: 0  Color: 0   Card:  2  Suit: 2  Color: 1
Card:  3  Suit: 0  Color: 0   Card:  3  Suit: 2  Color: 1
Card:  4  Suit: 0  Color: 0   Card:  4  Suit: 2  Color: 1
Card:  5  Suit: 0  Color: 0   Card:  5  Suit: 2  Color: 1
Card:  6  Suit: 0  Color: 0   Card:  6  Suit: 2  Color: 1
Card:  7  Suit: 0  Color: 0   Card:  7  Suit: 2  Color: 1
Card:  8  Suit: 0  Color: 0   Card:  8  Suit: 2  Color: 1
Card:  9  Suit: 0  Color: 0   Card:  9  Suit: 2  Color: 1
Card: 10  Suit: 0  Color: 0   Card: 10  Suit: 2  Color: 1
Card: 11  Suit: 0  Color: 0   Card: 11  Suit: 2  Color: 1
Card: 12  Suit: 0  Color: 0   Card: 12  Suit: 2  Color: 1
Card:  0  Suit: 1  Color: 0   Card:  0  Suit: 3  Color: 1
Card:  1  Suit: 1  Color: 0   Card:  1  Suit: 3  Color: 1
Card:  2  Suit: 1  Color: 0   Card:  2  Suit: 3  Color: 1
Card:  3  Suit: 1  Color: 0   Card:  3  Suit: 3  Color: 1
Card:  4  Suit: 1  Color: 0   Card:  4  Suit: 3  Color: 1
Card:  5  Suit: 1  Color: 0   Card:  5  Suit: 3  Color: 1
Card:  6  Suit: 1  Color: 0   Card:  6  Suit: 3  Color: 1
Card:  7  Suit: 1  Color: 0   Card:  7  Suit: 3  Color: 1
Card:  8  Suit: 1  Color: 0   Card:  8  Suit: 3  Color: 1
Card:  9  Suit: 1  Color: 0   Card:  9  Suit: 3  Color: 1
Card: 10  Suit: 1  Color: 0   Card: 10  Suit: 3  Color: 1
Card: 11  Suit: 1  Color: 0   Card: 11  Suit: 3  Color: 1
Card: 12  Suit: 1  Color: 0   Card: 12  Suit: 3  Color: 1


Fig. 20.16. Bit fields used to store a deck of cards.

It’s possible to specify an unnamed bit field, in which case the field is used as padding in the structure. For example, the structure definition uses an unnamed three-bit field as padding—nothing can be stored in those three bits. Member b is stored in another storage unit.

struct Example
{
   unsigned a : 13;
   unsigned   : 3; // align to next storage-unit boundary
   unsigned b : 4;
}; // end struct Example

An unnamed bit field with a zero width is used to align the next bit field on a new storage-unit boundary. For example, the structure definition

struct Example
{
   unsigned a : 13;
   unsigned   : 0; // align to next storage-unit boundary
   unsigned b : 4;
}; // end struct Example

uses an unnamed 0-bit field to skip the remaining bits (as many as there are) of the storage unit in which a is stored and align b on the next storage-unit boundary.


Image Portability Tip 20.4

Bit-field manipulations are machine dependent. For example, some computers allow bit fields to cross word boundaries, whereas others do not.



Image Common Programming Error 20.5

Attempting to access individual bits of a bit field with subscripting as if they were elements of an array is a compilation error. Bit fields are not “arrays of bits.”



Image Common Programming Error 20.6

Attempting to take the address of a bit field (the & operator may not be used with bit fields because a pointer can designate only a particular byte in memory and bit fields can start in the middle of a byte) is a compilation error.



Image Performance Tip 20.2

Although bit fields save space, using them can cause the compiler to generate slower-executing machine-language code. This occurs because it takes extra machine-language operations to access only portions of an addressable storage unit. This is one of many examples of the space–time trade-offs that occur in computer science.


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.171.58