You can declare such a field, but only inside a struct. It's called a
bit-field:
struct contains_two_bit{
unsigned char two_bit:2;
};
However, while two_bit itself takes up only two bits, the entire struct
necessarily takes up at least one entire byte, and might take up more
space than that. You don't save any actual space by defining such a type
unless you declare other bit-fields either immediately before or
immediately after that one, in which case it may use up less space than
if you declared them as non-bit-fields. Adjacent bit-fields are packed
into some addressable allocation unit, the size of which depends upon
the implementation. The order of those bit-fields within an allocation
unit also varies with the implementation. Whether or not a bit-field
that is smaller than the allocation unit size may straddle the boundary
between allocation units can also vary from one implementation to
another. For example, given
struct bit_fields {
bool a:1;
int8_t b:3;
int8_t c:5;
int8_t d:7;
int16_t e:11;
int16_t f:13;
}
An implementation that uses an allocation unit with a size of 8, which
allows bit fields to straddle allocation units, could implement that
type by storing the fields as follows:
byte 1: a, b, and the first four bits of c
byte 2: the last bit of c, and d
byte 3: the first 8 bits of e
byte 4: the last 3 bits of e, the first five bits of f
byte 5: the last 8 bits of e.
An implementation that uses an allocation unit with a size of 16 that
doesn't allow straddling could implement it as follows:
first 2 bytes: a, b, c d
next 2 bytes: e and 5 padding bits
last 2 bytes: f and 3 padding bits
You can't take the address of a bit-field, and you can't bind it to a
reference. If two bit-fields in a struct are separated from each other
only by other bit-fields, you cannot safely access both bit fields
concurrently. For these reasons, it's often not worthwhile to declare
things as bit-fields.