将位字段导出到数组

Export bitfield to an array

本文关键字:数组 字段      更新时间:2023-10-16

我已经声明了这个位字段。我想做的是以二进制形式获取比特字段的整个值,并将其转换为数组,这样我就可以使用索引并寻址每个"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};

这可能吗?有什么建议吗?提前感谢

如果您实际上是从uint8_t开始的,那么您不需要也不想摆弄位字段。。。

假设(a(Little Endian和(b(您可以编写一个未对齐的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 ;
}

参见亨利·s·沃伦的《黑客的喜悦》:-(


但是,如果你从位字段开始,那么你会遇到一个完全不同的问题:你真的不能对位字段的存储方式做出任何假设——你所能做的就是读取/写入单个字段。因此,您别无选择,只能将每个位字段复制到其各自的字节。。。如其他答案中所给出的。

不使用位字段,只使用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(可能更有效,但需要适当地改变移位和掩码(例如,uint16_t的4和15(。

如果您只想导出您的位字段,可以使用用户定义的从unionstd::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;
}
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