在结构体中访问位域

3

我对位字段的概念还不熟悉。我试图访问结构中的元素,但在aa=v处显示错误。

error: incompatible types when assigning to type ‘cc’ from type ‘long unsigned int ’

如果我将其强制转换为aa = (cc)v;,它会显示错误。

error: conversion to non-scalar type requested

我尝试通过声明一个指向结构体的指针来访问元素。在这种情况下我做得很好,但是在这种情况下我没有声明一个指向结构体的指针,我必须访问元素。如何解决这个错误。

提前感谢任何帮助。

#include<stdio.h>
typedef struct 
{
        unsigned long a:8;
    unsigned long b:8;
    unsigned long c:8;
    unsigned long d:8;
}cc;


int main()
{ 
        cc aa ;
    unsigned long v = 1458;
    printf("%d\n",sizeof(aa));
    aa=v;    // aa= (cc)v;
    printf("%d %d %d %d\n", aa.a,aa.b,aa.c,aa.d);

    return 0;
}

如果你需要8位大小的位域,我可能会使用inttypes.h中的uint8_t(如果这显而易见,那就抱歉)。 - m01
5个回答

7
如果您想要访问多种数据类型的相同数据,则需要在C中使用union。请查看以下代码片段,它将:
  1. 将其视为32位整数写入联合体
    (然后)
  2. 将数据作为4个单独的8位位域进行访问
    (并且为了保险起见)
  3. 再次将相同数据作为32位整数访问

#include<stdio.h>

typedef struct {
    unsigned long a:8;
    unsigned long b:8;
    unsigned long c:8;
    unsigned long d:8;
}bitfields;

union data{
    unsigned long i;
    bitfields bf;
};

int main()
{ 
    union data x;
    unsigned long v = 0xaabbccdd;
    printf("sizeof x is %dbytes\n",sizeof(x));

    /* write to the union treating it as a single integer */
    x.i = v;

    /* read from the union treating it as a bitfields structure */
    printf("%x %x %x %x\n", x.bf.a, x.bf.b, x.bf.c, x.bf.d);

    /* read from the union treating it as an integer */
    printf("0x%x\n", x.i);

    return 0;
}

请注意,当联合体作为整数访问时,系统的字节序决定了各个位域的顺序。因此,在32位x86 PC(小端)上运行上述程序将输出:

sizeof x is 4bytes
dd cc bb aa
0xaabbccdd

3

这是因为aa是一个结构体,而v不是,类型是不兼容的,就像错误信息所说的那样。即使cc是一个位域结构体,它仍然只能被用作结构体,具有单独的成员,而不像整数。


2

如果我理解正确,您想将一个4字节大小的long赋值给一个4字节大小的结构体。如果是的话,可以尝试以下方法:

 aa = *(cc*)&v;

然而,在这种情况下,您需要注意字节序。

0
使用这个:
aa.a = v;

不是

aa = v;

0

你试图将一个不兼容的long类型赋值给一个struct

你可以将cc的内部值赋给v:

cc c;
unsigned long v = 1458;
c.b = v;

如果你想让前8位在变量a中,你可以这样做:
cc c;
unsigned long v = 1458;
c.a = v % 255;
c.b = v / 255 % 65280;

那样做不会导致溢出吗? 8位bit字段可以容纳的最大整数值不是255吗? - verbose
1458的二进制值为:10110110010;我的目标是将前8位放入结构元素a中,即10110010 = 178;接下来的8位放入元素b中:101=5。如果我按照你说的做,第一个元素会取前8位,其余元素则显示为0。 - user2641184
那么你可以使用模块来实现。@user2641184 - No Idea For Name

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接