我宣布自己为位字段(u8表示未加整数8)
typedef struct build_field{
u8 build : 5;
u8 ability : 1;
u8 hability : 1;
u8 shinyness : 1;
} build_field;现在,我想转换一个函数返回的传入u8值,这样我就可以将它作为位字段使用。
build_field f = (build_field) func_that_returns_u8();此外,我还想将其转换回u8值。
u8 x = (u8) field;但是我的C编译器不允许我做任何这样的操作。知道怎么解决这个问题吗?
发布于 2016-04-08 09:05:38
使用工会:
union myunion
{
u8 value;
build_field field;
};
union myunion m;
m.value = func_that_returns_u8();
u8 a = m.ability;确保结构build_field中的成员之间没有填充,否则这将无法工作。
一个更明智的选择是从整数中提取位。假设值中的位与结构中的成员排序相同。要获得hability和ability的值,请执行以下操作:
u8 value = func_that_returns_u8();
build_field f = { 0 };
f.hability = ( ( unsigned int )value >> 6U ) & 1U;
f.ability = ( ( unsigned int )value >> 5U ) & 1U;发布于 2016-04-08 09:18:52
可以在C中返回整个结构,结合static,这也可以内联(从gcc中的-O1开始)
static build_field compose_field(unsigned char uc)
{
union {
unsigned char uc;
build_field bf;
} uni = {uc};
return uni.bf;
}用法
int main(void)
{
build_field val;
val = compose_field(0xa5 ); // "constructor"
printf(" {%u %u %u %u}\n"
, (unsigned int) val.build
, (unsigned int) val.ability
, (unsigned int) val.hability
, (unsigned int) val.shinyness
);
return 0;
}GCC输出与-O2:
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
movl $1, 20(%esp)
movl $0, 16(%esp)
movl $1, 12(%esp)
movl $5, 8(%esp)
movl $.LC0, 4(%esp)
movl $1, (%esp)
call __printf_chk
xorl %eax, %eax
leave
ret具有非常量参数:(uc = 0xa5 * random(); ):
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
call random
movl $-91, %ecx
xorl %edx, %edx
movl $.LC0, 4(%esp)
movl $1, (%esp)
imull %ecx, %eax
movb %al, %dl
movl %edx, %eax
shrl $7, %eax
movl %eax, 20(%esp)
movl %edx, %eax
shrl $6, %eax
andl $1, %eax
movl %eax, 16(%esp)
movl %edx, %eax
andl $31, %edx
shrl $5, %eax
andl $1, %eax
movl %eax, 12(%esp)
movl %edx, 8(%esp)
call __printf_chk
xorl %eax, %eax
leave
rethttps://stackoverflow.com/questions/36495580
复制相似问题