假设我们有一个
int
并且想要以布尔方式在 0
和 1
之间切换。我想到了以下几种可能性:
int value = 0; // May as well be 1
value = value == 0 ? 1 : 0;
value = (value + 1) % 2;
value = !value; // I was curious if that would do...
!0
是1
?_Bool
(或来自 stdbool.h 的 bool
)相同吗?如果不是,有什么区别?value = !value;
直接表达了你想要做的事情,并且它按照定义完全按照你想要做的事情做。
使用这个表达方式。
来自C99 6.5.3.3/5“一元算术运算符”:
逻辑非运算符的结果!如果其值是 0 如果操作数的值比较,则操作数比较不等于 0、1 等于 0。结果的类型为 int。表达式 !E 是等价的 到 (0==E)。
第三个似乎有效。为什么?谁决定!0 是 1?
C 标准保证
!0
是 1
。
还有其他可能性吗?例如按位运算符?
是的,您可以使用异或运算符:
value ^= 1;
顺便说一下,我更喜欢这个而不是
value = !value;
,因为关系运算符和相等运算符可以导致分支,而按位运算符通常不会。
value = 1 - value; // toggle from 0 to 1 ... or 1 to 0
// when you know initial value is either 0 or 1
根据架构的不同,替代方案可能会存在明显的性能问题:
但无论如何,优化的首要规则是不要优化不工作的代码。 要将 !a 替换为 a^1,必须 100% 确定它始终产生预期值。
value = (value ^ 1) & 1;
_Bool
会有相同的结果。与 _Bool 唯一不同的是,值被强制为 1 或 0。这意味着 bool x = 55;
将具有值 x == 1
编辑:由于我的脑残,更正了3中的公式。我发表评论是为了让人们看到我的花絮。
value = !value
似乎是最合理的,但您也可以使用 value = 1 - value
或 value ^= 1
。但如果 value
不是 0
或 1
,最后两个都会破裂。第一个仍然有效。
您的表情
value = value == 0 ? 1 : 0;
将与value = !value;
完全相同。您可以使用两者中的任何一个。
!0
始终是 1
并且 !(any non zero value)
也是 0
使用按位非运算符
var = ~var;