C语言 为什么在联合中定义结构时会丢失这些位

e5nszbig  于 2022-12-22  发布在  其他
关注(0)|答案(1)|浏览(144)

我遇到了以下问题,我在一个联合体中的结构中分配了一些位。我试图将它们与同一个联合体中的一个单独的结构重新组合。但是,当我在Individual中分配mvUpper时,我丢失了该数据或基于我在Individual中分配的值的一个有效位。(请注意,我只丢失了我在notIndividual中重组的部分的数据)请忽略名称,这是我在实现之前对工会的调查。

#include <stdio.h>
#include <string.h>
typedef union testing
{   
    struct Individual
    {  
    unsigned short mt  : 10;
    unsigned short mlbl : 3;
    unsigned short mvUpper :3;
    unsigned short mvLower :3;
    unsigned short mlUpper :2;
    unsigned short mlLower :5;
    }Individual;
    struct bE
    {
        unsigned int woo: 26;
    }bE;

    struct notIndividual
    {  
    unsigned short mt  : 10;
    unsigned short mlbl : 3;
    unsigned short mv :6 ;
    unsigned short ml : 7;
    }notIndividual;
} testing;

int main(int argc, char* argv[]){
    testing dothis;

    memset(&dothis,0,(sizeof(dothis)));

    printf("THIS IS THE SIZE of union%lu\n",sizeof(dothis));

    //printf("SIZE %d",sizeof(dothis.Individual));
    //printf("NOT SIZE %d",sizeof(dothis.notIndividual));

    dothis.Individual.mvUpper=3;

    printf("Testing MT%u\n",dothis.Individual.mt);
    printf("Testing MLBL %u\n",dothis.Individual.mlbl);
    printf("Testing MVUpper %u\n",dothis.Individual.mvUpper);
    printf("Testing MVLower %u\n",dothis.Individual.mvLower);
    printf("Testing ML Upper %u\n",dothis.Individual.mlUpper);
    printf("Testing ML Lower %u\n",dothis.Individual.mlLower);

    printf("Testing Mt %u\n",dothis.notIndividual.mt);
    printf("Testing Mlbl %u\n",dothis.notIndividual.mlbl);
    printf("Testing MV %u \n",dothis.notIndividual.mv);
    printf("Testing ML %u\n",dothis.notIndividual.ml);
    
    printf("THIS IS THE WORD %u\n", dothis.bE.woo>>21);

    return 1;
}

这是我看不懂的输出

THIS IS THE SIZE of union4
Testing MT0
Testing MLBL 0
Testing MVUpper 3
Testing MVLower 0
Testing ML Upper 0
Testing ML Lower 0
Testing Mt 0
Testing Mlbl 0
Testing MV 0 
Testing ML 0
THIS IS THE WORD 0

我试着测试一个简单的通过联合进行位转换的方法。

jxct1oxe

jxct1oxe1#

首先,结构体中位域的组织是由实现定义的,所以你不能依赖于某个特定的布局。也就是说,下面是最有可能发生的情况。
每个位域的基类型都是unsigned short,所以编译器会尝试将每个位域分组为该大小的单元。
对于第一个结构,布局如下所示:

struct Individual
{  
unsigned short mt  : 10;     // 10 bits used in unit 0
unsigned short mlbl : 3;     // 13 bits used in unit 0
unsigned short mvUpper :3;   // 16 bits used in unit 0
unsigned short mvLower :3;   // 3 bits used in unit 1
unsigned short mlUpper :2;   // 5 bits used in unit 1
unsigned short mlLower :5;   // 10 bits used in unit 1
}Individual;

第二,

struct notIndividual
{  
unsigned short mt  : 10;   // 10 bits used in unit 0
unsigned short mlbl : 3;   // 13 bits used in unit 0
unsigned short mv :6 ;     // 6 bits used in unit 1 (not enough in unit 0)
unsigned short ml : 7;     // 13 bits used in unit 1
}notIndividual;

如果将所有的位域都更改为基本类型unsigned int,则位域的压缩程度会更高,并且会得到预期的结果。

相关问题