How to get array of bits in a structure?

前端 未结 6 2198
走了就别回头了
走了就别回头了 2020-12-14 01:00

I was pondering (and therefore am looking for a way to learn this, and not a better solution) if it is possible to get an array of bits in a structure.

相关标签:
6条回答
  • 2020-12-14 01:42

    You can also use an array of integers (ints or longs) to build an arbitrarily large bit mask. The select() system call uses this approach for its fd_set type; each bit corresponds to the numbered file descriptor (0..N). Macros are defined: FD_CLR to clear a bit, FD_SET to set a bit, FD_ISSET to test a bit, and FD_SETSIZE is the total number of bits. The macros automatically figure out which integer in the array to access and which bit in the integer. On Unix, see "sys/select.h"; under Windows, I think it is in "winsock.h". You can use the FD technique to make your own definitions for a bit mask. In C++, I suppose you could create a bit-mask object and overload the [] operator to access individual bits.

    0 讨论(0)
  • 2020-12-14 01:44

    NOT POSSIBLE - A construct like that IS NOT possible(here) - NOT POSSIBLE

    One could try to do this, but the result will be that one bit is stored in one byte

    #include <cstdint>
    #include <iostream>
    using namespace std;
    
    #pragma pack(push, 1)
    struct Bit
    {
        //one bit is stored in one BYTE
        uint8_t a_:1;
    };
    #pragma pack(pop, 1)
    typedef Bit bit;
    
    struct B
    {
        bit bits[4];
    };
    
    int main()
    {
        struct B b = {{0, 0, 1, 1}};
        for (int i = 0; i < 4; ++i)
            cout << b.bits[i] <<endl;
    
        cout<< sizeof(Bit) << endl;
        cout<< sizeof(B) << endl;
    
        return 0;
    }
    

    output:

    0 //bit[0] value
    0 //bit[1] value
    1 //bit[2] value
    1 //bit[3] value
    1 //sizeof(Bit), **one bit is stored in one byte!!!**
    4 //sizeof(B), ** 4 bytes, each bit is stored in one BYTE**
    

    In order to access individual bits from a byte here is an example (Please note that the layout of the bitfields is implementation dependent)

    #include <iostream>
    #include <cstdint>
    using namespace std;
    
    #pragma pack(push, 1)
    struct Byte
    {
        Byte(uint8_t value):
            _value(value)
        {
        }
        union
        {
        uint8_t _value;
        struct {
            uint8_t _bit0:1;
            uint8_t _bit1:1;
            uint8_t _bit2:1;
            uint8_t _bit3:1;
            uint8_t _bit4:1;
            uint8_t _bit5:1;
            uint8_t _bit6:1;
            uint8_t _bit7:1;
            };
        };
    };
    #pragma pack(pop, 1)
    
    int main()
    {
        Byte myByte(8);
        cout << "Bit 0: " << (int)myByte._bit0 <<endl;
        cout << "Bit 1: " << (int)myByte._bit1 <<endl;
        cout << "Bit 2: " << (int)myByte._bit2 <<endl;
        cout << "Bit 3: " << (int)myByte._bit3 <<endl;
        cout << "Bit 4: " << (int)myByte._bit4 <<endl;
        cout << "Bit 5: " << (int)myByte._bit5 <<endl;
        cout << "Bit 6: " << (int)myByte._bit6 <<endl;
        cout << "Bit 7: " << (int)myByte._bit7 <<endl;
    
        if(myByte._bit3)
        {
            cout << "Bit 3 is on" << endl;
        }
    }
    
    0 讨论(0)
  • 2020-12-14 01:50

    In C++ you use std::bitset<4>. This will use a minimal number of words for storage and hide all the masking from you. It's really hard to separate the C++ library from the language because so much of the language is implemented in the standard library. In C there's no direct way to create an array of single bits like this, instead you'd create one element of four bits or do the manipulation manually.

    EDIT:

    The 1 bit unsigned int is a valid type, so why shouldn't you be able to get an array of it?

    Actually you can't use a 1 bit unsigned type anywhere other than the context of creating a struct/class member. At that point it's so different from other types it doesn't automatically follow that you could create an array of them.

    0 讨论(0)
  • 2020-12-14 01:50

    this is abusive, and relies on an extension... but it worked for me:

    struct __attribute__ ((__packed__)) A
    {
        unsigned int bit0:1;
        unsigned int bit1:1;
        unsigned int bit2:1;
        unsigned int bit3:1;
    };
    union U
    {
        struct A structVal;
        int intVal;
    };
    
    int main()
    {
        struct A a = {1, 0, 1, 1};
        union U u;
        u.structVal = a;
        for (int i =0 ; i<4; i++)
        {
            int mask = 1 << i;
            printf("%d\n", (u.intVal &  mask) >> i);
        }
        return 0;
    }
    
    0 讨论(0)
  • 2020-12-14 02:02

    C++ would use std::vector<bool> or std::bitset<N>.

    In C, to emulate std::vector<bool> semantics, you use a struct like this:

    struct Bits {
        Word word[];
        size_t word_count;
    };
    

    where Word is an implementation-defined type equal in width to the data bus of the CPU; wordsize, as used later on, is equal to the width of the data bus.

    E.g. Word is uint32_fast_t for 32-bit machines, uint64_fast_t for 64-bit machines; wordsize is 32 for 32-bit machines, and 64 for 64-bit machines.

    You use functions/macros to set/clear bits.

    To extract a bit, use GET_BIT(bits, bit) (((bits)->)word[(bit)/wordsize] & (1 << ((bit) % wordsize))).

    To set a bit, use SET_BIT(bits, bit) (((bits)->)word[(bit)/wordsize] |= (1 << ((bit) % wordsize))).

    To clear a bit, use CLEAR_BIT(bits, bit) (((bits)->)word[(bit)/wordsize] &= ~(1 << ((bit) % wordsize))).

    To flip a bit, use FLIP_BIT(bits, bit) (((bits)->)word[(bit)/wordsize] ^= (1 << ((bit) % wordsize))).

    To add resizeability as per std::vector<bool>, make a resize function which calls realloc on Bits.word and changes Bits.word_count accordingly. The exact details of this is left as a problem.

    The same applies for proper range-checking of bit indices.

    0 讨论(0)
  • 2020-12-14 02:02

    You can create a bit list by using a struct pointer. This will use more than a bit of space per bit written though, since it'll use one byte (for an address) per bit:

    struct bitfield{
        unsigned int bit : 1;
    };
    struct bitfield *bitstream;
    

    Then after this:

    bitstream=malloc( sizeof(struct bitfield) * numberofbitswewant );
    

    You can access them like so:

    bitstream[bitpointer].bit=...
    
    0 讨论(0)
提交回复
热议问题