使用双重逻辑非(!!)运算符感到困惑[重复]

Posted

技术标签:

【中文标题】使用双重逻辑非(!!)运算符感到困惑[重复]【英文标题】:Confused by use of double logical not (!!) operator [duplicate] 【发布时间】:2013-04-17 23:19:42 【问题描述】:

我有一些广泛使用!! 的C++ 代码。我有点困惑,因为据我所知,!! 本身并不是一个操作员,而是两个! 一个接一个。这意味着!!foofoo 相同。

!! 有什么地方和理由吗?我在想它是否可能有一点明智的意义?因此,您首先对foo 执行一些位操作,然后对结果执行!?但我似乎不记得! 被用作有点明智的运算符,并且似乎也没有找到任何参考告诉我它是。据我所知,! 仅用作逻辑运算符,在这种情况下

!!foo == foo

【问题讨论】:

也可以写x+++++y+1,但这是个坏主意。 @GrahamBorland 现在我要去那里投票,作为这个的副本。 您可能还想阅读这篇文章:what is !! in c?. @msw 不,你不能。在两个序列点之间多次修改是未定义的行为。 !! 定义完美,对应触发安全布尔转换运算符。这对于optionalvariant 或任何智能指针特别有用。 【参考方案1】:

它可以用作将foo 转换为布尔表达式的速记。出于某种原因,您可能只想将非布尔表达式转换为 true 或 false。

foo = !!foo 将把foo 变成1 如果它不为零,如果它已经是,则将它留在0

【讨论】:

【参考方案2】:

此技术用于在布尔上下文中对变量进行安全评估。如果您与布尔(operator bool())进行正常对话,则不相关的变量(具有不同类型)可能会以不需要的方式参与布尔表达式。实现了返回否定布尔值的operator! 定义。它的结果必须再次被否定。只需看看Safe bool idiom。

【讨论】:

【参考方案3】:

这不是双重否定那么简单。例如,如果您有x == 5,则应用两个!运算符(!!x),它将变为 1 - 因此,它用于规范化 0, 1 范围内的布尔值。

请注意,您可以将零用作布尔值 false,将非零值用作布尔值 true,但您可能需要将结果标准化为 0 或 1,此时 !! 很有用。

x != 0 ? 1 : 0相同。

另外,请注意,如果foo 不在0, 1 集合中,这将不正确

!!foo == foo

#include <iostream>

using namespace std;

int main()

        int foo = 5;

        if(foo == !!foo)
        
                cout << "foo == !!foo" << endl;
        
        else
        
                cout << "foo != !!foo" << endl;
        



        return 0;

打印foo != !!foo

【讨论】:

可能的用例是什么? 假设您在某个地方将 bool 存储为 1 或 0,以位或其他形式存储。你检查的值是 5(这会被认为是真的),你基本上可以把 5 变成 1。 布尔 x = !0; // true bool x = !-15 // false int i = x;看看这个 更正式一点,它的结果是truebool 类型的值为 truefalse。在算术上下文中,它们分别转换为 10 我在编译器上使用了这种技术,当我将int 隐式转换为bool(性能警告:值将被转换为 0 或 1)时,该编译器会报错。我的选择是做一个 C 风格的 bool 演员表(我认为这是一个坏习惯),做 0 != v (之后的 ?1:0 是多余的)这会造成操作顺序的模糊性迫使 ()ing (在至少要弄清楚发生了什么),或static_cast&lt;bool&gt;( v ) 过于冗长。 !! 将可隐式转换为 bool 的类型转换为 bool 而不会发出警告并作为一元(因此是紧密绑定的)运算符。【参考方案4】:

如果foo 不是bool 类型,那么!!foo 将是。所以!!foo 可以是 1 或 0。

【讨论】:

01ints,而不是 bools。我们在这里谈论的是 C++;也许你把它和 C 混淆了? 你是对的。我应该说真假。 :)【参考方案5】:

如果foo != 0,那么!!foo == 1。转换为 bool 基本上是一个技巧。

【讨论】:

1 不是bool。这是int @Kerrek SB 我知道,我指的是实际值。

以上是关于使用双重逻辑非(!!)运算符感到困惑[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何使用保存在变量中的运算符符号执行操作[重复]

对 c 中的 -(--a) 与 --(-a) 感到困惑

==和===在php中的用法[重复]

!! c 运算符,是否两个?

Java中的逻辑运算顺序令人困惑

循环遍历目录中的所有文件[重复]