Unlike some other computer languages, C/C++ has a built-in feature called a bit-field
that allows you to access a single bit. Bit-fields can be useful for a number of reasons,
such as:
If storage is limited, you can store several Boolean (true/false) variables in
one byte.
Certain devices transmit status information encoded into one or more bits
within a byte.
Certain encryption routines need to access the bits within a byte.
Although these tasks can be performed using the bitwise operators, a bit-field can
add more structure (and possibly efficiency) to your code.
To access individual bits, C/C++ uses a method based on the structure. In fact,
a bit-field is really just a special type of structure member that defines how long,
in bits, the field is to be. The general form of a bit-field definition is
struct struct-type-name {
type name1 : length;
type name2 : length;
..
.
type nameN : length;
} variable_list;
Here, type is the type of the bit-field and length is the number of bits in the field.
A bit-field must be declared as an integral or enumeration type. Bit-fields of length
1 should be declared as unsigned, because a single bit cannot have a sign.
Bit-fields are frequently used when analyzing input from a hardware device.
For example, the status port of a serial communications adapter might return a
status byte organized like this:
that allows you to access a single bit. Bit-fields can be useful for a number of reasons,
such as:
If storage is limited, you can store several Boolean (true/false) variables in
one byte.
Certain devices transmit status information encoded into one or more bits
within a byte.
Certain encryption routines need to access the bits within a byte.
Although these tasks can be performed using the bitwise operators, a bit-field can
add more structure (and possibly efficiency) to your code.
To access individual bits, C/C++ uses a method based on the structure. In fact,
a bit-field is really just a special type of structure member that defines how long,
in bits, the field is to be. The general form of a bit-field definition is
struct struct-type-name {
type name1 : length;
type name2 : length;
..
.
type nameN : length;
} variable_list;
Here, type is the type of the bit-field and length is the number of bits in the field.
A bit-field must be declared as an integral or enumeration type. Bit-fields of length
1 should be declared as unsigned, because a single bit cannot have a sign.
Bit-fields are frequently used when analyzing input from a hardware device.
For example, the status port of a serial communications adapter might return a
status byte organized like this:
Bit Meaning When Set
0 Change in clear-to-send line
1 Change in data-set-ready
2 Trailing edge detected
3 Change in receive line
4 Clear-to-send
5 Data-set-ready
6 Telephone ringing
7 Received signal
You can represent the information in a status byte using the following bit-field:
struct status_type {
unsigned delta_cts: 1;
unsigned delta_dsr: 1;
unsigned tr_edge: 1;
unsigned delta_rec: 1;
unsigned cts: 1;
unsigned dsr: 1;
unsigned ring: 1;
unsigned rec_line: 1;
} status;
You might use a routine similar to that shown here to enable a program to determine
when it can send or receive data.
status = get_port_status();
if(status.cts) printf("clear to send");
if(status.dsr) printf("data ready");
To assign a value to a bit-field, simply use the form you would use for any other type
of structure element. For example, this code fragment clears the ring field:
status.ring = 0;
As you can see from this example, each bit-field is accessed with the dot operator.
However, if the structure is referenced through a pointer, you must use the −> operator.
You do not have to name each bit-field. This makes it easy to reach the bit you
want, bypassing unused ones. For example, if you only care about the cts and dsr
bits, you could declare the status_type structure like this:
struct status_type {
unsigned : 4;
unsigned cts: 1;
unsigned dsr: 1;
} status;
Also, notice that the bits after dsr do not need to be specified if they are not used.
It is valid to mix normal structure members with bit-fields. For example,
struct emp {
struct addr address;
float pay;
unsigned lay_off: 1; /* lay off or active */
unsigned hourly: 1; /* hourly pay or wage */
unsigned deductions: 3; /* IRS deductions */
};
defines an employee record that uses only 1 byte to hold three pieces of information:
the employee's status, whether the employee is salaried, and the number of deductions.
Without the bit-field, this information would have taken 3 bytes.
Bit-fields have certain restrictions. You cannot take the address of a bit-field. Bitfields
cannot be arrayed. They cannot be declared as static. You cannot know, from
machine to machine, whether the fields will run from right to left or from left to right;
this implies that any code using bit-fields may have some machine dependencies.
Other restrictions may be imposed by various specific implementations, so check the
user manual for your compiler.
want, bypassing unused ones. For example, if you only care about the cts and dsr
bits, you could declare the status_type structure like this:
struct status_type {
unsigned : 4;
unsigned cts: 1;
unsigned dsr: 1;
} status;
Also, notice that the bits after dsr do not need to be specified if they are not used.
It is valid to mix normal structure members with bit-fields. For example,
struct emp {
struct addr address;
float pay;
unsigned lay_off: 1; /* lay off or active */
unsigned hourly: 1; /* hourly pay or wage */
unsigned deductions: 3; /* IRS deductions */
};
defines an employee record that uses only 1 byte to hold three pieces of information:
the employee's status, whether the employee is salaried, and the number of deductions.
Without the bit-field, this information would have taken 3 bytes.
Bit-fields have certain restrictions. You cannot take the address of a bit-field. Bitfields
cannot be arrayed. They cannot be declared as static. You cannot know, from
machine to machine, whether the fields will run from right to left or from left to right;
this implies that any code using bit-fields may have some machine dependencies.
Other restrictions may be imposed by various specific implementations, so check the
user manual for your compiler.
No comments:
Post a Comment