有没有办法打印位而不使用C中的循环?

时间:2014-09-07 10:14:31

标签: c bit-manipulation

现在,我的工作是:

void print_bits(unsigned int x)
{
    int i;
    for(i=WORD_SIZE-1; i>=0; i--) {
        (x & (1 << i)) ? putchar('1') : putchar('0');
    }
    printf("\n");
}

此外,如果有一个独立于字大小的解决方案(在我的示例中目前设置为32),那将会很棒。

4 个答案:

答案 0 :(得分:3)

这个怎么样:

void print2Bits(int a) {
    char* table[] = {
        "00",
        "01",
        "10",
        "11"
    };
    puts(table[a & 3]);
}

void printByte(int a) {
    print2Bits(a >> 6);
    print2Bits(a >> 4);
    print2Bits(a >> 2);
    print2Bits(a);
}

void print32Bits(int a) {
    printByte(a >> 24);
    printByte(a >> 16);
    printByte(a >> 8);
    printByte(a);
}

我认为,你越接近编写没有循环的二进制数字。

答案 1 :(得分:2)

您可以尝试itoa。虽然它不在标准C lib中,但它在大多数C编译器中都可用。

void print_bits(int x)
{
    char bits[33];
    itoa(x, bits, 2);
    puts(bits);
}

答案 2 :(得分:2)

不是在循环中对putcharprintf进行多次调用,而是首先构建临时字符串然后通过一次调用将其输出到例如更高效。 puts

void print_bits(unsigned int x)
{
    const unsigned int n = sizeof(x) * CHAR_BIT;
    unsigned int mask = 1 << (n - 1);
    char s[n + 1];

    for (unsigned int i = 0; i < n; ++i)
    {
        s[i] = (x & mask) ? '1' : '0';
        mask >>= 1;
    }
    s[n] = '\0';
    puts(s);
}

LIVE DEMO

答案 3 :(得分:1)

这是我在前一段时间发现的字节的一种小黑客方式。尽管它不是最好的解决方案,但我认为它值得链接在这里。 http://gynvael.coldwind.pl/n/c_cpp_number_to_binary_string_01011010

void to_bin(unsigned char c, char *out) {
    *(unsigned long long*)out = 0x3030303030303030ULL // ASCII '0'*8
        + (((c * 0x8040201008040201ULL)   // spread out eight copies of c
           >>7) & 0x101010101010101ULL);  // shift to LSB & mask
}

@cmaster提供的方法是最佳和干净的。尽管如此,以8位的部分方式执行它可能会更好。您可以使用您的方法在循环中构造表,以避免手动编写256个字符串。我不认为记忆也是一个问题(需要大约2kB)。

虽然我认为没有循环可以为任何大小的变量做到这一点。