对于右移直到零的循环,并包括零

时间:2016-09-20 21:34:39

标签: c for-loop bit-shift

是否有更优雅的方式来执行以下for循环。检查零然后中断的if语句看起来很丑,但如果我不包含它,代码将无限循环。

for (int i = 8; i >= 0; i >>= 1) {
    printf("%d", i);
    if (i == 0) {
        break;
    }
}

理想的输出应该是:

8
4
2
1
0

即使我说for循环,也可以使用任何循环结构,例如或者做什么

5 个答案:

答案 0 :(得分:2)

  

是否有更优雅的方式来执行以下for循环。检查零然后中断的if语句看起来很丑,但如果我不包含它,代码将无限循环。

如果你包含它,那么在for语句中提供循环终止条件毫无意义。优雅可能在旁观者的眼中,但由于你的循环终止条件总会得到满足,我可能会改写这样的循环:

for (int i = 8; ; i >>= 1) {
    printf("%d", i);
    if (i == 0) {
        break;
    }
}

或者,您可以对其进行重组,以便在终止测试后执行右移,但在循环体的其余部分之前执行:

for (unsigned int i = 8 << 1; i; ) {
    i >>= 1;
    printf("%u", i);
}

答案 1 :(得分:1)

如果以位号而不是位掩码开头,则可以像这样编写循环

for ( int bit=3, mask=1<<bit; bit >= -1; bit--, mask >>= 1 ) {
    printf( "%d\n", mask );
}

答案 2 :(得分:0)

我能做的最好的事情是:

for(int i = 8;;) {
    printf("%d", i);
    if (!i) break;
    i >>= 1;
}

一些(N + .5)循环可以打包到条件子句中;但这不是其中之一。

答案 3 :(得分:0)

因为你知道你总是想要打印“0”,你可以:

for (int i = 8; i > 0; i >>= 1) {
  printf("%d", i);
}
printf("0");

或者,您可以先左移'“起始值”,然后执行:

for (int i = 8 << 1; i > 0;) {
  i >>= 1;
  printf("%d", i);
}

此方法的缺点是丢失了位宽。如果起始值很大,则左移会出现溢出。

答案 4 :(得分:-1)

这是我不那么简单但只有一行代码:

#include <stdio.h>

int main(void) {
    int i = 32;
    while(printf("%d\n", i), i >>= 1, !i ? printf("0\n"), 0 : 1);
}

我希望它有所帮助! :)