C语言实现列印出二进数格式

April 2, 2018

printf函式作为标准库中强大的IO工具而受青睐,可以说是所有初心者学习C语言必须接触的函式。但是,printf中的转译字元组中很遗憾的没有包含输出二进数的转译方法。虽然说大部分时候,我们都可以用输出16进数以替代,而且列印出二进数也实在没有甚么意义。可有的时候,就是有这个必要。

提前说明,我没有实现%b的效果,我只是用了另一个方法列印出变数的二进数值。

我这里提供了两种方法列印之。

其一,使用结构体

首先我们制订一个结构体,该结构体一共有8各成员,使用:运算子使每个成员占1个位元。所以一共是8bit,也就是刚好一个char

struct bit{
    unsigned char _0:1;
    unsigned char _1:1;
    unsigned char _2:1;
    unsigned char _3:1;
    unsigned char _4:1;
    unsigned char _5:1;
    unsigned char _6:1;
    unsigned char _7:1;
};

然后我们宣告一个该等位体的变数b,用之指向某个数据a的地址,然后,用b->_0b->_1这样的方式得到每一个位元做输出即可。可以用sizeof(a)/sizeof(char)的方式得知一共要进行几次输出。

具体代码就是:

int main(){
    int a = 50;
    int i;

    for(i=sizeof(a)/sizeof(char)-1; i>=0; i--){
        struct bit *b = (int)&a+i;
        printf("%d%d%d%d%d%d%d%d",b->_7,b->_6,b->_5,b->_4,b->_3,b->_2,b->_1,b->_0);
    }
    printf("\n");
}

另外,如果结构体中的变数类型不能只宣告为unsigned,必须要宣告为unsigned char

否则,下面的断言是不会通过的。

assert(sizeof(struct bit) == sizeof(char));

其二,使用位运算子

和方法一基本相同,使用sizeof(a)/sizeof(char)获取要进行输出的次数,然后将要输出的数a强制转换为unsigned char,然后输出其中的每一位。

for(i=sizeof(a)/sizeof(char)-1; i>=0; i--){
    int k;
    for(k=7; k>=0; k--){
        printf("%d",((*(unsigned char*)((int)&a+i)) & (0x01<<k))>>k);
    }
}

我们可以封装为一个巨集

#define printb_(b,size) {                                                   \
                        int i;                                              \
                        for(i=size-1; i>=0; i--){                           \
                            int k;                                          \
                            for(k=7; k>=0; k--){                            \
                                printf("%d",((*(unsigned char*)((int)&b+i)) & (0x01<<k))>>k);   \
                            }                                               \
                        }}

#define printb(b)       printb_(b,sizeof(b)/sizeof(char))

就可以很轻松的使用之了。

int main(){
    int a = 50;
    printb(a);
}