0

下面的代码在打印一些十进制数字时以看似无休止的循环结束。

int main(){
    show(0xBADECAFU);
}

void show(unsigned a){
    unsigned pos=0;
    for(; pos<UINT_MAX; pos++)
        printf("%u", (1U<<pos) & a);
}

下面的代码实际上显示了十六进制数的位。为什么第一个程序运行不正常而第二个程序运行不正常?

int main(){
     show(0xBADECAFU);
}

void show(unsigned n){
    unsigned pos=31, count=1;
    for(; pos!=UINT_MAX; pos--, count++){
        printf("%u", n>>pos & 1U);
}
4

3 回答 3

4

中没有UINT_MAXunsigned int。但是,有一些CHAR_BIT * sizeof(unsigned int)位。

/* nb: this prints bits LSB first */
void show(unsigned a){
    unsigned pos=0;
    for(; pos < CHAR_BIT*sizeof(unsigned); pos++)
        printf("%u", (1U<<pos) & a ? 1 : 0);
}

考虑你的第二种情况,你循环直到posequals UINT_MAX。这将正确*打印出 32 位unsigned,假设下溢发生~0并且sizeof(unsigned)至少为 4。

您的第二个示例可以稍微改进:

void show(unsigned n){
    int pos = (CHAR_BIT * sizeof(unsigned)) - 1;
    for(; pos >= 0; pos--) {
        printf("%u", (n>>pos) & 1U);
    }
}

*您的“打印”位的代码很奇怪,在我的示例中,我已经修复了它。

于 2012-04-27T01:48:41.313 回答
2

UINT_MAX 是可以存储在无符号整数变量中的最大值。它与位数没有直接关系。

您的第一个循环正在增加大量整数。

您的第二个循环从 31 减少到 ??? (无符号,那么当你减 0 时会发生什么? - 看起来你很幸运并且 0-1 = UINT_MAX)

于 2012-04-27T01:53:29.153 回答
0

这只是一个猜测。

我认为第一个问题是(1U<<pos)调用未定义的行为 if pos >= (sizeof(unsigned int) * CHAR_BIT)。在这种情况下,编译器可以自由地为所欲为。它可能假设您永远不会创建这种情况,因此pos必须始终< (sizeof(unsigned int) * CHAR_BIT) < UINT_MAX,因此可以优化循环条件。不幸的是,这种“优化”给你留下了一个无限循环。

于 2012-04-27T04:24:38.967 回答