Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有一种方法可以在不使用C循环的情况下打印位?_C_Bit Manipulation - Fatal编程技术网

有没有一种方法可以在不使用C循环的情况下打印位?

有没有一种方法可以在不使用C循环的情况下打印位?,c,bit-manipulation,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"); } 无效打印位(无符号整数x) { int i; 对于(i=WORD\u SIZE-1;i>=0;i--){ (x&(1这个怎么样:

现在,我要做的是:

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");
}
无效打印位(无符号整数x)
{
int i;
对于(i=WORD\u SIZE-1;i>=0;i--){
(x&(1这个怎么样:

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);
}

我想,这是你写一个没有循环的二进制数的最后一步。

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

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

这里是一个小黑客的方式来做它的字节我发现了一些时间。我认为它值得在这里链接,尽管它不是最好的解决方案。


@cmaster提供的方法是最佳且干净的。但是以8位的部分进行操作可能会更好。您可以使用您的方法在循环中构造表,以避免手动写入256个字符串。我不认为内存也会是一个问题(大约需要2kB)


尽管我不认为有一种方法可以在没有循环的情况下对任何大小的变量执行此操作。

与在循环中多次调用
putchar
printf
相比,首先构建一个临时字符串,然后通过一次调用(例如
put
)输出可能更有效:

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);
}
无效打印位(无符号整数x)
{
常量无符号整数n=sizeof(x)*字符位;
无符号整数掩码=1>=1;
}
s[n]='\0';
卖出(s);
}

>SeZOFF(X)* CalaBIT 对于小型的类型,你可以考虑一个查找表。这不适合于更大的类型。我能问一个问题吗?为什么你不用一个循环来做它呢?它只是为了测试还是其他什么?你希望通过消除循环?过早优化?“打印”来具体实现什么?“尽可能快”几乎从未在同一句话中使用;-)printf

(或
put
putchar
)的巨大开销比任何循环展开的增益都要大。将字符存储在缓冲区中,然后只打印一次应该更好。1.这仍然或多或少是一个循环(使用4次迭代而不是32次)。2.
int
的大小在所有平台上都不一定是32位(即,它不是由C语言标准规定的)。因此您应该使用
sizeof(int)
以及
CHAR\u位
(在文件
limits.h
中定义)。应用这些修复程序最终将迫使您使用循环。@barakmanos第2点正是我调用上一个函数
print32Bits()
而不是
printInt()的原因
。没错,没有循环,你就没有足够的灵活性来适应不同的整数大小。而且,是的,它几乎是一个展开的循环。但是分层分解很好地减少了代码量。实际上这里的代码比简单的
for
循环中的代码多得多。@barakmanos,这就是为什么我永远不会写的原因但是OP要求:-)顺便说一句,从数学上讲,最好的表条目大小应该是
log(32)
,即每个字符串5个字符。这可能会使实现更加困难,但每个字符串4个字符可能会得到优化,并且相对容易实现。
#包括
并将
33
更改为
sizeof(x)* CARYBIT + 1  BTW, ITOA最有可能仍然执行OP希望避免的循环……也考虑到ITOA不是ANSI-C也不是C++。@ AcC造饰者找不到ITOA。在哪里(头文件)它是声明的吗?@NikhilVidhani尝试包括
stdlib.h
。您可以参考。正如我在回答中提到的,它是一个广泛的非标准扩展,因此可能
itoa
在您的编译器中不可用。请在此处提供您的答案,以便即使链接消失,它仍然有效。标准的东西。【我现在觉得自己长大了!】我不认为将某人(有点长)的文章(或由我解释得更糟)复制到我的帖子上会是个坏主意。你不认为这样做会是个坏主意吗?所以,做吧:-)
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);
}