C语言 如何在 C 中切换 int / _Bool
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13154073/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to toggle an int / _Bool in C
提问by riha
Suppose we have an intand want to toggle it between 0and 1in a boolean fashion. I thought of the following possibilities:
假设我们有一个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...
- The third one seems to work. Why? Who decides that
!0is1? - Is something wrong with any of these?
- Are there other possibilities? e.g. bitwise operators?
- Which offers the best performance?
- Would all that be identical with
_Bool(orboolfrom stdbool.h)? If not, what are the differences?
- 第三个似乎有效。为什么?谁决定那
!0是1? - 这些有什么问题吗?
- 还有其他可能吗?例如按位运算符?
- 哪个提供最好的性能?
- 所有这些都与
_Bool(或bool来自 stdbool.h)相同吗?如果不是,有什么区别?
EDIT: Many great answers with lots of valuable information, thanks! Unfortunately, I can only accept one.
编辑:很多很好的答案,提供了很多有价值的信息,谢谢!不幸的是,我只能接受一个。
回答by Michael Burr
value = !value;expresses what you want to do directly, and it does exactly what you want to do by definition.
value = !value;直接表达你想做什么,它按照定义做你想做的。
Use that expression.
用那个表情。
From C99 6.5.3.3/5 "Unary arithmetic operators":
来自 C99 6.5.3.3/5“一元算术运算符”:
The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int. The expression !E is equivalent to (0==E).
逻辑否定运算符的结果!如果其操作数的值比较不等于 0,则为 0,如果其操作数的值比较等于 0,则为 1。结果的类型为 int。表达式 !E 等价于 (0==E)。
回答by ouah
The third one seems to work. Why? Who decides that !0 is 1?
第三个似乎有效。为什么?谁决定 !0 是 1?
C Standard guarantees that !0is 1.
C 标准保证!0是1.
Are there other possibilities? e.g. bitwise operators?
还有其他可能吗?例如按位运算符?
Yes, you can use the exclusive OR operator:
是的,您可以使用异或运算符:
value ^= 1;
value ^= 1;
By the way I prefer this to value = !value;as relational and equality operators can result to branching and bitwise operators usually do not.
顺便说一下,我更喜欢这个, value = !value;因为关系运算符和相等运算符会导致分支,而按位运算符通常不会。
回答by Patrick Schlüter
- the language was designed that way.
- Use the 3rd one, the others are right but unnecessarly complicated and therefore hiding the intent.
value = (value ^ 1) & 1;- They're all the same after optimisation.
_Boolwould have the same results. The only thing different with _Bool is that values are coerced to be either 1 or 0. Meaning thatbool x = 55;will have the valuex == 1
- 语言就是这样设计的。
- 使用第三个,其他是对的,但不必要地复杂,因此隐藏了意图。
value = (value ^ 1) & 1;- 优化后都一样。
_Bool会有相同的结果。与 _Bool 唯一不同的是值被强制为 1 或 0。这意味着bool x = 55;将具有值x == 1
EDIT: Corrected the formula in 3 because of my brainfart. I let the comments so that people can see my blooper.
编辑:由于我的脑放屁,更正了 3 中的公式。我让评论,以便人们可以看到我的花絮。
回答by Scott Stensland
value = 1 - value; // toggle from 0 to 1 ... or 1 to 0
// when you know initial value is either 0 or 1
回答by Aki Suihkonen
There can be noticeable performance issues with the alternatives depending on the architecture:
根据架构的不同,替代方案可能存在明显的性能问题:
- !a might need in some architectures comparison and branching, which can be expensive depending on the pattern of 'a'
- on some architectures there is conditional move (which is branchless), but
which may require still 3 instructions to complete (with dependencies)
- on some architectures there is conditional move (which is branchless), but
- 1-a most likely needs two instructions in many architectures
- counter example: ARM has reverse subtraction RSB%r0, %r0, #1
- 1^a can be implemented in many architecture with a single instruction
- a=(a+1) % 2 will be most likely optimized to a=(a+1)&1, which requires 2 instructions
- !a 在某些架构中可能需要比较和分支,这可能会很昂贵,具体取决于 'a' 的模式
- 在某些架构上有条件移动(无分支),但
可能仍需要 3 条指令才能完成(有依赖关系)
- 在某些架构上有条件移动(无分支),但
- 1-a 在许多架构中很可能需要两条指令
- 反例:ARM 有反向减法RSB%r0, %r0, #1
- 1^a 可以通过一条指令在许多架构中实现
- a=(a+1) % 2 最有可能优化为 a=(a+1)&1,这需要 2 条指令
But anyway the first rule of optimization is that don't optimize a non working code. To replace !a with a^1, one has to be 100% certain that it produces always the expected value.
但无论如何,优化的第一条规则是不要优化非工作代码。要将 !a 替换为 a^1,必须 100% 确定它始终产生预期值。
回答by detunized
value = !valueseems the most reasonable one, but you can also use value = 1 - valueor value ^= 1. But the last two would both break if valueis not 0or 1. The first one would still work.
value = !value似乎是最合理的一种,但您也可以使用value = 1 - valueor value ^= 1。但如果value不是0或,最后两个都会中断1。第一个仍然可以工作。
回答by CCoder
Your expression value = value == 0 ? 1 : 0;will work exactly like value = !value;. You can use any of the two.
您的表达式value = value == 0 ? 1 : 0;将与value = !value;. 您可以使用两者中的任何一个。
!0is always 1and also !(any non zero value)is 0
!0永远1也!(any non zero value)被0
回答by tkerwood
In C# you can use Math.Abs(value -1)to toggle between zero and one as integers.
在 C# 中,您可以使用Math.Abs(value -1)整数在 0 和 1 之间切换。

