首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将标量类型转换为非标量并向后转换?

如何将标量类型转换为非标量并向后转换?
EN

Stack Overflow用户
提问于 2016-04-08 09:01:26
回答 2查看 75关注 0票数 2

我宣布自己为位字段(u8表示未加整数8)

代码语言:javascript
复制
typedef struct build_field{

    u8 build : 5;
    u8 ability : 1;
    u8 hability : 1;
    u8 shinyness : 1;

} build_field;

现在,我想转换一个函数返回的传入u8值,这样我就可以将它作为位字段使用。

代码语言:javascript
复制
build_field f = (build_field) func_that_returns_u8();

此外,我还想将其转换回u8值。

代码语言:javascript
复制
u8 x = (u8) field;

但是我的C编译器不允许我做任何这样的操作。知道怎么解决这个问题吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-08 09:05:38

使用工会:

代码语言:javascript
复制
union myunion
{
    u8 value;
    build_field field;
};

union myunion m;
m.value = func_that_returns_u8();
u8 a = m.ability;

确保结构build_field中的成员之间没有填充,否则这将无法工作。

一个更明智的选择是从整数中提取位。假设值中的位与结构中的成员排序相同。要获得habilityability的值,请执行以下操作:

代码语言:javascript
复制
u8 value = func_that_returns_u8();
build_field f = { 0 };
f.hability = ( ( unsigned int )value >> 6U ) & 1U;
f.ability = ( ( unsigned int )value >> 5U ) & 1U;
票数 4
EN

Stack Overflow用户

发布于 2016-04-08 09:18:52

可以在C中返回整个结构,结合static,这也可以内联(从gcc中的-O1开始)

代码语言:javascript
复制
static build_field compose_field(unsigned char uc)
{
union {
        unsigned char uc;
        build_field bf;
        } uni = {uc};
return uni.bf;
}

用法

代码语言:javascript
复制
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:

代码语言:javascript
复制
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(); ):

代码语言:javascript
复制
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
    ret
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36495580

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档