【问题标题】:Issue with struct bit values in cc中的结构位值问题
【发布时间】:2019-06-17 07:04:38
【问题描述】:

您好,我正在尝试使用 struct 在 c 中将十进制值转换为二进制。以下是我的代码:

#include <stdio.h>
struct binary{
    int bin:1 ;
};
void main(void){
    int dec = 24;
    struct binary bi[32];
    //printf("%d\n",sizeof(struct binary));
    for(int i = 0 ; i < 32 ; i++){
        int k = dec & 1;
        bi[i].bin = k;
        dec = dec >> 1;
        //printf("%d ",k);
    }
    for(int i = 31 ; i >= 0 ; i--){
        printf("%d ",bi[i].bin);
    }
}

当我打印值时,我在位字段 (0000_0000_0000_0000_0000_0000_000-1_-1000) 中看到 -1 代替了 1。有人可以知道为什么会这样吗?而且我认为结构的大小是 1 位,但是当我执行 sizeof(struct binary) 时,它显示为 4 个字节,你知道为什么吗?

TIA

【问题讨论】:

  • @sandywho 使用 unsigned int bin:1 ;
  • int bin:1; 表示您仅使用 1 位有符号值。编译器会将其保存在整数大小的内存中。要获得 1 而不是 -1,请将 bit 定义为 unsigned bin : 1;
  • @sandywho 当您打印sizeof(struct binary) 时,您得到了什么价值?如果你打印sizeof(bi),你会得到什么尺寸?
  • 为此使用结构没有任何优势,与仅使用 intunsigned int 数组相比,由于结构填充,sizeof(struct binary) 将成为 sizeof(int)
  • @user3386109 分别为 4 和 128

标签: c struct bit-manipulation bit


【解决方案1】:

定义一个 1 位大的位域是毫无意义的,而且标准定义也很差。未指定位域的大多数方面,包括 int 位域应计为有符号还是无符号。最好的建议是 100% 远离位域,尤其是在处理二进制内存映射时。

值得注意的是,您实际上并没有转换任何东西 - 您只是逐位复制一个 32 位 int,您可以一次复制整个 32 位。由于程序中的所有数据都已经是二进制形式,因此无需进行任何转换。只需调整打印程序:

uint32_t dec = 0xDEADBEEF;
const size_t bits = 8*sizeof(dec);
for(size_t i=0; i<bits; i++)
{
  uint32_t mask = (1u << (bits-i-1));  // mask from MSB to LSB
  printf("%d", (_Bool)(dec & mask));   // convert zero/non-zero value into 0 or 1
}

输出:

11011110101011011011111011101111

【讨论】:

    【解决方案2】:

    那是因为您使用的是带符号的 int 并且分配了一位用于表示符号。

    你应该使用 unsigned int 例如:

    #include <stdio.h>
    struct binary{
        unsigned int bin:1 ;
    };
    void main(void){
        int dec = 24; 
        struct binary bi[32];
    
        for(int i = 0 ; i < 32 ; i++){
            int k = dec & 1;
            bi[i].bin = k;
            dec = dec >> 1;
    
        }   
        for(int i = 31 ; i >= 0 ; i--){
            printf("%u ",bi[i].bin);
        }   
    }
    

    【讨论】:

    • int 位域是有符号还是无符号,标准没有定义。它很可能被认为是无符号的——我们不知道,因为标准对位域的定义太差了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-24
    • 1970-01-01
    • 2021-08-18
    • 2010-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多