Экспорт битового поля в массив - PullRequest
0 голосов
/ 20 февраля 2020

Я объявил это битовое поле. Я пытаюсь получить все значение битового поля в двоичном виде и преобразовать его в массив, чтобы я мог использовать индекс и обращаться к каждому значению «1».

union{
    struct shape{
        uint8_t p0 : 1;
        uint8_t p1 : 1;
        uint8_t p2 : 1;
        uint8_t p3 : 1;
        uint8_t p4 : 1;
        uint8_t p5 : 1;
        uint8_t p6 : 1;
        uint8_t p7 : 1;
    };
    uint8_t row;
}rows[8*2+4];

я пытаюсь экспортировать битовое поле в массив, например, uint8_t tab [8] = {0,1,1,0,0,1,0,1};

Это вообще возможно? Какие-нибудь советы? Заранее спасибо

Ответы [ 4 ]

1 голос
/ 20 февраля 2020

Если вы на самом деле начинаете с uint8_t, то вам не нужно или не нужно возиться с битовыми полями ...

... при условии (a) Little- Endian и (б), что вы можете написать без выравнивания uint64_t:

void explode_byte(uint8_t r[8], uint8_t b)
{
  uint64_t x ;

  x  = b ;
  x |= x << (32 - 4) ;
  x |= x << (16 - 2) ;
  x |= x << ( 8 - 1) ;

  *(uint64_t*)r = x & (uint64_t)0x0101010101010101 ;
}

См. "Восторг Хакера" Генри С. Уорреном: -)


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

0 голосов
/ 20 февраля 2020
rows[8] = (union row){.p0 = 0,.p1 = 1,.p2 = 1,.p3 = 0,.p4 = 0,.p5= 1,.p6 = 0,.p7 = 1};

или

rows[8].row = {b01100101};, если вы сами определяете все складские места, как показано ниже, или не переносимы rows[8].row = {0b01100101};

#ifndef __BIN_8BITS__
#define __BIN_8BITS__

#define b00000000 0x0000
#define b00000001 0x0001
#define b00000010 0x0002
#define b00000011 0x0003
#define b00000100 0x0004
#define b00000101 0x0005
#define b00000110 0x0006
#define b00000111 0x0007
#define b00001000 0x0008
#define b00001001 0x0009
#define b00001010 0x000A
#define b00001011 0x000B
#define b00001100 0x000C
#define b00001101 0x000D
#define b00001110 0x000E
#define b00001111 0x000F
#define b00010000 0x0010
#define b00010001 0x0011
#define b00010010 0x0012
#define b00010011 0x0013
#define b00010100 0x0014
#define b00010101 0x0015
#define b00010110 0x0016
#define b00010111 0x0017
#define b00011000 0x0018
#define b00011001 0x0019
#define b00011010 0x001A
#define b00011011 0x001B
#define b00011100 0x001C
#define b00011101 0x001D
#define b00011110 0x001E
#define b00011111 0x001F
#define b00100000 0x0020
#define b00100001 0x0021
#define b00100010 0x0022
#define b00100011 0x0023
#define b00100100 0x0024
#define b00100101 0x0025
#define b00100110 0x0026
#define b00100111 0x0027
#define b00101000 0x0028
#define b00101001 0x0029
#define b00101010 0x002A
#define b00101011 0x002B
#define b00101100 0x002C
#define b00101101 0x002D
#define b00101110 0x002E
#define b00101111 0x002F
#define b00110000 0x0030
#define b00110001 0x0031
#define b00110010 0x0032
#define b00110011 0x0033
#define b00110100 0x0034
#define b00110101 0x0035
#define b00110110 0x0036
#define b00110111 0x0037
#define b00111000 0x0038
#define b00111001 0x0039
#define b00111010 0x003A
#define b00111011 0x003B
#define b00111100 0x003C
#define b00111101 0x003D
#define b00111110 0x003E
#define b00111111 0x003F
#define b01000000 0x0040
#define b01000001 0x0041
#define b01000010 0x0042
#define b01000011 0x0043
#define b01000100 0x0044
#define b01000101 0x0045
#define b01000110 0x0046
#define b01000111 0x0047
#define b01001000 0x0048
#define b01001001 0x0049
#define b01001010 0x004A
#define b01001011 0x004B
#define b01001100 0x004C
#define b01001101 0x004D
#define b01001110 0x004E
#define b01001111 0x004F
#define b01010000 0x0050
#define b01010001 0x0051
#define b01010010 0x0052
#define b01010011 0x0053
#define b01010100 0x0054
#define b01010101 0x0055
#define b01010110 0x0056
#define b01010111 0x0057
#define b01011000 0x0058
#define b01011001 0x0059
#define b01011010 0x005A
#define b01011011 0x005B
#define b01011100 0x005C
#define b01011101 0x005D
#define b01011110 0x005E
#define b01011111 0x005F
#define b01100000 0x0060
#define b01100001 0x0061
#define b01100010 0x0062
#define b01100011 0x0063
#define b01100100 0x0064
#define b01100101 0x0065
#define b01100110 0x0066
#define b01100111 0x0067
#define b01101000 0x0068
#define b01101001 0x0069
#define b01101010 0x006A
#define b01101011 0x006B
#define b01101100 0x006C
#define b01101101 0x006D
#define b01101110 0x006E
#define b01101111 0x006F
#define b01110000 0x0070
#define b01110001 0x0071
#define b01110010 0x0072
#define b01110011 0x0073
#define b01110100 0x0074
#define b01110101 0x0075
#define b01110110 0x0076
#define b01110111 0x0077
#define b01111000 0x0078
#define b01111001 0x0079
#define b01111010 0x007A
#define b01111011 0x007B
#define b01111100 0x007C
#define b01111101 0x007D
#define b01111110 0x007E
#define b01111111 0x007F
#define b10000000 0x0080
#define b10000001 0x0081
#define b10000010 0x0082
#define b10000011 0x0083
#define b10000100 0x0084
#define b10000101 0x0085
#define b10000110 0x0086
#define b10000111 0x0087
#define b10001000 0x0088
#define b10001001 0x0089
#define b10001010 0x008A
#define b10001011 0x008B
#define b10001100 0x008C
#define b10001101 0x008D
#define b10001110 0x008E
#define b10001111 0x008F
#define b10010000 0x0090
#define b10010001 0x0091
#define b10010010 0x0092
#define b10010011 0x0093
#define b10010100 0x0094
#define b10010101 0x0095
#define b10010110 0x0096
#define b10010111 0x0097
#define b10011000 0x0098
#define b10011001 0x0099
#define b10011010 0x009A
#define b10011011 0x009B
#define b10011100 0x009C
#define b10011101 0x009D
#define b10011110 0x009E
#define b10011111 0x009F
#define b10100000 0x00A0
#define b10100001 0x00A1
#define b10100010 0x00A2
#define b10100011 0x00A3
#define b10100100 0x00A4
#define b10100101 0x00A5
#define b10100110 0x00A6
#define b10100111 0x00A7
#define b10101000 0x00A8
#define b10101001 0x00A9
#define b10101010 0x00AA
#define b10101011 0x00AB
#define b10101100 0x00AC
#define b10101101 0x00AD
#define b10101110 0x00AE
#define b10101111 0x00AF
#define b10110000 0x00B0
#define b10110001 0x00B1
#define b10110010 0x00B2
#define b10110011 0x00B3
#define b10110100 0x00B4
#define b10110101 0x00B5
#define b10110110 0x00B6
#define b10110111 0x00B7
#define b10111000 0x00B8
#define b10111001 0x00B9
#define b10111010 0x00BA
#define b10111011 0x00BB
#define b10111100 0x00BC
#define b10111101 0x00BD
#define b10111110 0x00BE
#define b10111111 0x00BF
#define b11000000 0x00C0
#define b11000001 0x00C1
#define b11000010 0x00C2
#define b11000011 0x00C3
#define b11000100 0x00C4
#define b11000101 0x00C5
#define b11000110 0x00C6
#define b11000111 0x00C7
#define b11001000 0x00C8
#define b11001001 0x00C9
#define b11001010 0x00CA
#define b11001011 0x00CB
#define b11001100 0x00CC
#define b11001101 0x00CD
#define b11001110 0x00CE
#define b11001111 0x00CF
#define b11010000 0x00D0
#define b11010001 0x00D1
#define b11010010 0x00D2
#define b11010011 0x00D3
#define b11010100 0x00D4
#define b11010101 0x00D5
#define b11010110 0x00D6
#define b11010111 0x00D7
#define b11011000 0x00D8
#define b11011001 0x00D9
#define b11011010 0x00DA
#define b11011011 0x00DB
#define b11011100 0x00DC
#define b11011101 0x00DD
#define b11011110 0x00DE
#define b11011111 0x00DF
#define b11100000 0x00E0
#define b11100001 0x00E1
#define b11100010 0x00E2
#define b11100011 0x00E3
#define b11100100 0x00E4
#define b11100101 0x00E5
#define b11100110 0x00E6
#define b11100111 0x00E7
#define b11101000 0x00E8
#define b11101001 0x00E9
#define b11101010 0x00EA
#define b11101011 0x00EB
#define b11101100 0x00EC
#define b11101101 0x00ED
#define b11101110 0x00EE
#define b11101111 0x00EF
#define b11110000 0x00F0
#define b11110001 0x00F1
#define b11110010 0x00F2
#define b11110011 0x00F3
#define b11110100 0x00F4
#define b11110101 0x00F5
#define b11110110 0x00F6
#define b11110111 0x00F7
#define b11111000 0x00F8
#define b11111001 0x00F9
#define b11111010 0x00FA
#define b11111011 0x00FB
#define b11111100 0x00FC
#define b11111101 0x00FD
#define b11111110 0x00FE
#define b11111111 0x00FF

#endif
0 голосов
/ 20 февраля 2020

Если вы хотите просто экспортировать свои битовые поля, это возможно с помощью пользовательского преобразования из вашего union в std::array. Обратите внимание, что возможно только чтение битов (не установлено).

union{
    struct shape{
        uint8_t p0 : 1;
        uint8_t p1 : 1;
        uint8_t p2 : 1;
        uint8_t p3 : 1;
        uint8_t p4 : 1;
        uint8_t p5 : 1;
        uint8_t p6 : 1;
        uint8_t p7 : 1;
    } bits;

    operator std::array<bool , 8>(){
        std::array<bool , 8> exported_array;
        exported_array[ 0 ] = bits.p0;
        exported_array[ 1 ] = bits.p1;
        exported_array[ 2 ] = bits.p2;
        exported_array[ 3 ] = bits.p3;
        exported_array[ 4 ] = bits.p4;
        exported_array[ 5 ] = bits.p5;
        exported_array[ 6 ] = bits.p6;
        exported_array[ 7 ] = bits.p7;

        return exported_array;
    }

    uint8_t row;
} rows[8*2+4];

int main()
{
    rows[0].row = static_cast<uint8_t>( 643211 );
    std::array< bool , 8 > data = rows[ 0 ];

    for ( auto bit : data )
        std::cout << static_cast<int>( bit );
}

Но я не предлагаю использовать этот метод. Насколько я понимаю, вы читаете значение откуда-то, и вы хотите получить доступ / манипулировать битами, как массив. std :: bitset - хороший вариант для этого.

Возможная реализация, подобная этой:

#include <cstdint>
#include <iostream>
#include <bitset>

int main()
{
    uint8_t data_comes_from_somewhere = 0b01001001;
    std::string data_comes_from_somewhere_as_string { "11101001" };
    std::bitset<8> bitfields { data_comes_from_somewhere };
    std::bitset<8> bitfields_2 { data_comes_from_somewhere_as_string };

    std::cout << bitfields << std::endl;
    std::cout << bitfields_2 << std::endl;

    // Set leftmost bit
    bitfields[ 7 ] = 1;
    int leftmost_bit = bitfields[ 7 ];

    std::cout << bitfields << std::endl;
    std::cout << leftmost_bit << std::endl;
}
0 голосов
/ 20 февраля 2020

Вместо использования битовых полей, используйте только массив uint8_t и обращайтесь к каждому биту, используя сдвиги и маски. На самом деле в стандарте C нет другого способа получить доступ к битам по индексу (не считая каких-либо реализаций библиотеки).

uint8_t data[SIZE];
...
data[bitIndex >> 3] |= 1 << (bitIndex & 7);  // set bit at bitIndex
data[bitIndex >> 3] &= ~(1 << (bitIndex & 7); // clear bit at bitIndex
bitValue = !!(data[bitIndex >> 3] & (1 << bitIndex & 7)); // read bit at bitIndex

Использование больших типов (16, 32, 64) может быть более эффективным, но требует соответствующего изменились смены и маски (например, 4 и 15 для uint16_t).

...