2013-10-05 29 views
-5

我是新来的C和学习逐位运算符CI是如何工作的要检查是否有地址的最显著设置或不我如何展示地址0x80至1 << 31二进制

int main() 
    { 

    int addr=0x0fffffff; 

    if(addr&0x80) 
    { 
     Printf("Bit is set"); 
    } 
    else 
    printf("Bit is not set"); 
    return 0; 
    } 

编辑:我想0x80被表示为1000 0000 0000 0000 0000 0000 0000 0000,我在过去看过这样的实现,不需要使用一些宏来编写所有的位,但不能在其中回忆它?

+1

你为什么期望它给“位未设置”? “0x80”等于128,并且该位肯定设置在“0x0fffffff”中。 –

+0

你为什么不试试? – marcadian

+0

好吧,这没有任何意义。为什么不写'(1 << 31)'或什么的? – harold

回答

2

您的代码 INT ADDR = 0x0fffffff; 和 if(addr & 0x80) 导致此情况始终为真。

0x0fffffff => 0000 1111 1111 1111 .... 1111 1111 
where 0x80 =>       1000 0000 
------------------------------------------------- 
bitwise AND        1000 0000 -> non zero means true! 
+0

是@Hirofumo你是对的,但我想有什么方法可以代表0x80为1000 0000 0000 0000 0000 0000 0000 0000?手形式。 –

+0

如果你有兴趣这样做,然后更改'0x80'到'0x80000000' – haccks

+1

你可能陷入'endian'的陷阱。实际上,小端机器在32位格式中的值为0x80,为'80 00 00 00'。但是,它们也以相同的方式将0x0fffffff存储为'ff ff ff 0f':)。在通常的数字/逻辑计算中,您不必关心末端。 – HirofumiTamori

0

if(addr&0x80) 

条件addr&0x80成立(返回一个非零值if),它相当于

if(a nonzero value) // any nonzero value treated as true 

这就是为什么它是印刷Bit is set

+0

0x80在二进制将是1000 0000 0000 0000 0000 0000 0000 0000现在检查它对0x0fffffff会给0。这种方式我想。 –

+4

谁告诉你'0x80'会是'1000 0000 0000 0000 0000 0000 0000 0000'? – haccks

+0

罚@haccks它不是,但想代表0x80为1000 0000 0000 0000 0000 0000 0000 0000,我不想写,如果我的条件像if(addr&0x80000000),我想我不能把我的问题正确的方式。 –

1

cnon zero值为true。所以你的条件将是真实的。

你的条件将评估为10000000b = 128 = true

+0

添加0bXXXX前缀到二进制数字或您的文章看起来垃圾;) – Skeen

1

您可以检查是否通过使用掩码〜(〜0U >> 1)设置最高有效位。下面是一些代码改编自你:

#include <stdio.h> 

int main() { 
    int addr=0x0fffffff; 
    unsigned int mask = ~(~0U >> 1); 

    if (addr & mask) { 
     printf("Bit is set"); 
    } 
    else 
     printf("Bit is not set"); 
    return 0; 
} 

因为你是新的C,面具看起来有点怪异,所以让我们看看这里发生了什么:

〜0U是,每一个位无符号数设为1:一元〜运算符否定0上的每一位,从而使得每一位1〜0U >> 1将它全部向右移动一位,所以现在你有(在32位机器上):

01111111111111111111111111111111 

再次否定它,这是〜(〜0U >> 1),得出:

10000000000000000000000000000000 

所以现在你有一个只有最重要的位设置的数字,这是用作测试其他数字的掩码。

使用这种构造是可移植的,因为您不依赖于数字的大小。无论int中有多少位,〜(〜0U >> 1)将始终工作。

该数字被声明为无符号的,因为右移运算符可以在常规整数中导致符号扩展,我们不希望这样。使用无符号数字,右移总是插入前导0。

+0

感谢Filipe对你的回应,我们可以做一些这样的事情吗(addr&(1 << 31))? –

+1

您可以,但该代码假设整数是32位,因此它不是便携式的。 –

相关问题