2016-03-07 63 views
3

确实我有什么编译器“思考”这种争议:什么双重否定用C

a = 8; 
b = !!a; 

那么,b == 0x01?是TRUE总是0x01或者它可能是0xFF,0xFFFF,0xFFFFFFFF等。

如果我只想提取0x00如果(a == 0)0x01如果(a > 0)这样做的双重否定方法的作品?

换句话说:要获得结果只有0或1,有什么更好的使用?

一)a>0?1:0; B)!!a

我希望你明白我的问题。

+0

Duplicate没有解决问题的尾部;重新开放。 – Bathsheba

+5

将此类优化留给编译器。编写最可读的代码。 –

+0

如果你想“提取0x01”,如果a> 0,那么这些方法是等价的,如果a没有符号或有符号但总是保证保持非负值。但是我没有看到你在任何地方说过。一般来说,'a> 0'和'!! a'是不一样的。那么你真的需要哪一个? – AnT

回答

1

!!a将为0或1,并且将是类型int。对于零a将为0,否则为0。

至于您的选择(a)和(b),它们是而不是等效,因为a为负值的可能性。除此之外,你可能会认为a > 0 ? 1 : 0更清晰,但在性能关键型应用程序!!a可能会更好,因为它不会分支,而三元条件可能会转储管道。但一个好的编译器会优化任何一种方式。我很少使用,因为像if (a)if (!!a)等功能是等同的。

+0

我想知道!被优化为无操作! –

+0

@arif(和bathsheba)http://goo.gl/RpznmQ尝试在该列表中找到一个编译器,它为两种可能性生成不同的代码(显然,'a> 0?1:0'将产生不同的代码, a'是无符号的。) – rici

4

是,b == 1。任何布尔运算符的结果总是为0或1。你可以做的更好,虽然...

我想只提取为0x00,如果(A == 0)和0x01,如果(A> 0)

b = a > 0;最准确地反映你的规则。

+0

感谢您的快速投票! –

+0

任何布尔运算符的**输出**为0或1.在'a == -1'的例子中,'a'和'-1'是运算符的输入,但结果是'0'或'1'。 – QuestionC

0

在速度方面,我认为这高度依赖于您使用的编译器和处理器。

较长的表达式会产生一个可执行文件大4-16个字节。

+0

关于可执行文件的大小会有哪些编译器? – rici

4

您尚未得到足够的信息来辨别!!a是否适合您。

你说你确实需要a > 0的结果。但是,如果a已签名并且保留负值,则这不等于!!a。如果这是可能的,那么答案显然是“不”。

!!a相当于a != 0而不是a > 0

0

逻辑非操作者!的结果是0,如果它的操作数的值不相等的比较为0,1,如果其操作数的值进行比较等于0,结果具有类型int。表达式!E相当于(0==E)。 C11§6.5.3.35

b以下将典型值为1(或可能为-1,见下文)。

a = 8; 
b = !!a; 

那么,b == 0x01

是(见下面)

TRUE总是0x01也可能是0xFF0xFFFF0xFFFFFFFF等..?

<stdbool.h>true与整数常量1. TRUE宏不是由C标准定义。各种实现定义它的值为1.其可能有其他值。它当然应该是非零的。

有什么更好的使用?

A) a>0?1:0 
B) !!a 

两个结果在int01值。预期合理到良好的编译器会为两者生成相同的代码(如果a未签名)。使用1)坚持你的团体编码标准的形式,否则2)最好地表达了当时代码的含义。这将导致(bool)型的第三种选择:

C) (bool) a 

如果a签署,然后a>0?1:0不等同于!!aa != 0 ? 1 :0相当于!!a


*如果b是1位签位字段,b = !!8将有值为-1。