c 中的结构位值问题
Issue with struct bit values in c
您好,我正在尝试使用 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);
}
}
当我打印值时,我在位域中看到 -1 而不是 1 (0000_0000_0000_0000_0000_0000_000-1_-1000)。有人知道为什么会这样吗?而且我认为结构的大小是 1 位,但是当我执行 sizeof(struct binary) 时,它显示为 4 个字节,你知道为什么吗?
TIA
那是因为您使用的是带符号的 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);
}
}
定义一个大 1 位的 bit-field 是毫无意义的,而且标准也没有很好地定义它。 bit-field 的大多数方面都没有指定,包括 int
bit-field 应该算作有符号还是无符号。最好的建议是保持 100% 远离 bit-fields,尤其是在处理二进制内存映射时。
值得注意的是,您实际上并没有转换任何东西——您只是在复制一个 32 位 int bit-by-bit,您可以一次复制整个 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
您好,我正在尝试使用 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);
}
}
当我打印值时,我在位域中看到 -1 而不是 1 (0000_0000_0000_0000_0000_0000_000-1_-1000)。有人知道为什么会这样吗?而且我认为结构的大小是 1 位,但是当我执行 sizeof(struct binary) 时,它显示为 4 个字节,你知道为什么吗?
TIA
那是因为您使用的是带符号的 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);
}
}
定义一个大 1 位的 bit-field 是毫无意义的,而且标准也没有很好地定义它。 bit-field 的大多数方面都没有指定,包括 int
bit-field 应该算作有符号还是无符号。最好的建议是保持 100% 远离 bit-fields,尤其是在处理二进制内存映射时。
值得注意的是,您实际上并没有转换任何东西——您只是在复制一个 32 位 int bit-by-bit,您可以一次复制整个 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