2016-05-27 30 views
0

在c中,我知道一个无符号字符的大小是1个字节(= 1个字节= 8位),我知道一个无符号字符其实是一个介于0和255之间的整数值,现在如果我有以下使用unsigned char变量:这个变量的

如何获取无符号字符的每一位的值?

unsigned char c = 255; //(this value can be any value from 0 to 255) 


我怎么能拿8个元素表示每个位值的表(0或1)? (如下所示:{1,1,1,1,1,1,1,1})有没有简单的方法可以在c中执行此操作?

+3

注意:在罕见的机器上,'unsigned char'大于8位。使用'CHAR_BIT'。 – chux

+0

这是数学,纯粹简单(?)数学。 – alk

+0

我在我的acer e-15上测试了它,然后sizeof(无符号字符)给我1(字节)作为结果,这并不像你想象的那么稀少...... – SWIIWII

回答

3

到提取C位的常见方法是使用移位操作:

int bits[8]; 
for (int i = 0 ; i != 8 ; i++) { 
    bits[i] = (c & (1 << i)) != 0; 
} 

1 << i产生二进制数与1i个位置,即1 ,10 ,100 ,1000 等等。

运营商&使用1 << i作为“掩码”,在掩码的值中选择标记为1的单个位c。比较!= 0完成作业,根据位的值产生零个或一个。

另一种方法是移动c到右侧,并与1掩蔽,像这样:

int bits[8]; 
for (int i = 0 ; i != 8 ; i++) { 
    bits[i] = (c >> i) & 1; 
} 

这类似于第一种方法,但掩蔽在至少显著比特位置来完成。

注意:CHAR_BIT设置为8以外的数字的计算机上,这将只提取较低的8位。

+0

在某些TI芯片上这会失败,例如,一个字节不是8位。 – DevNull

+0

@SWIIWII这是正确的,它只是先写出LSB(“向后”)。二进制中的83是0b1010011,所以如果你想让你的MSB成为第一个,在作业中使用位[7-i]而不是位[i]'。 – dasblinkenlight

+0

@dasblinkenlight我不同意。 TC/OP只是说明(不正确)一个字节= 8位,而不是在他/她的具体平台上,这是特定情况。 – DevNull

1

位运算身旁(这更好,我会说标准的方式来做到这一点),你可以使用工会访问单位:注意

typedef union { 
    unsigned char c; 
    struct { 
     unsigned char b0 :1; 
     unsigned char b1 :1; 
     unsigned char b2 :1; 
     unsigned char b3 :1; 
     unsigned char b4 :1; 
     unsigned char b5 :1; 
     unsigned char b6 :1; 
     unsigned char b7 :1; 
    }; 
} byte_struct; 

int main(int argc, char** argv) { 
    byte_struct c; 
    c.c = 0xaa; 

    printf("%u\n", c.b7); 
    printf("%u\n", c.b6); 
    printf("%u\n", c.b5); 
    printf("%u\n", c.b4); 
    printf("%u\n", c.b3); 
    printf("%u\n", c.b2); 
    printf("%u\n", c.b1); 
    printf("%u\n", c.b0); 

    return (EXIT_SUCCESS); 
} 

:是实现定义单位变量的顺序,所以你应该小心,并使用编译器特定的标志来强制执行命令

+5

不要这样做:*单元内位字段的分配顺序(高阶至 低阶或低阶至高阶)是实现定义的*英文中:位字段成员b0 '可能不代表最不重要的位。 – 2501

+1

@ 2501是的,它是实现定义的,但并不意味着你不能使用它,你可以通过编译器的标志来控制它,从而依赖它,当然你也可以拍摄你的腿 –

相关问题