为啥双重否定强制值成为布尔值?

Posted

技术标签:

【中文标题】为啥双重否定强制值成为布尔值?【英文标题】:Why does double negation force values to become a bool?为什么双重否定强制值成为布尔值? 【发布时间】:2018-07-18 05:43:07 【问题描述】:

如果 x 是一个像 1010 这样的 4 位字,并且您执行了 !!x 操作,

第一个 !x 不会返回 0101, 第二个 !(!x) 返回 1010?

而是返回 ...0001 或 ...0000。这是为什么呢?

【问题讨论】:

也许先弄清楚单否定的作用是什么? 相关:***.com/questions/9229601/what-is-in-c-code(我发誓有这样一个更好的问题,但目前找不到......) 你混淆了!~ 第一个 ! 将任何非零值转换为 false,第二个 ! 使其成为 true(反之亦然) 在 C 中,“双重否定强制值变为布尔值”并不完全正确。 ! 结果是 int,而不是 bool,其值为 0 或 1。 【参考方案1】:

! 是一个布尔运算符,因此它将数字转换为布尔值(任何非零值都是true,零总是false)。另一个 ! 反转布尔值。

【讨论】:

在 C 中(因为帖子是双重标记的 - 叹息),! 结果不是bool,而是int 是的,在 C 中没有 bools(不像 true/false),但它是一个 int 值。 (01)但在 C++ 和 C# 中它是 bool 不同意“在 C 中没有布尔值(不像真/假)”。从 C99 开始,C 具有布尔类型 _Bool(又名 bool 通过 <stdbool.h>)。 ! 的 C 返回类型仍然是 int 抱歉,不知道。 贴有 C C++标签的帖子很遗憾会产生这样的问题 - 这不是你的错。【参考方案2】:

! 运算符执行逻辑否定。如果它的参数不为零,则结果为 0。如果其参数为 0,则结​​果为 1。

您所描述的是按位补码运算符,用~ 表示。

这些都在C standard 的第 6.5.3.3 节中进行了描述:

4 ~ 运算符的结果是其(提升的)操作数的按位补码(也就是说,结果中的每一位都被设置当且仅 如果未设置转换后的操作数中的相应位)。这 对操作数执行整数提升,结果有 提升的类型。如果提升的类型是无符号类型,则 表达式~E 等价于可表示的最大值 那个类型减去E

5 逻辑否定运算符!的结果如果其操作数的值比较不等于0则为0,如果其操作数的值比较不等于1 比较等于 0。结果的类型为 int。表达式!E 是 相当于(0==E)

【讨论】:

我认为 C 的 ! 可以更好地描述为 "!=0" 运算符。当应用于逻辑值时,它会否定它们,但它也可以应用于其他类型,例如浮点值或指针。【参考方案3】:

在 C 中,!x 是 1 或 0,因此!!x 是“折叠到 0 或 1 运算符”,因为任何非零数都映射到 1,而 0 保持原样。这可能在某些情况下很有用。

在 C++ 中,!x 是一个bool 类型,所以!!x 是一个“折叠为假或真运算符”,因为任何非零数都映射到true,并且零被映射到false

【讨论】:

@Adrian 我废弃了 c#。也许你可以回答那个问题。 无论如何,这个问题并不真正适用于c#。 C# 没有隐式整数到布尔转换。 @Adrian 被重新标记保存! 你为什么不简单地做(bool)x(_Bool)x @Ayxan:这会改变表达式的类型。

以上是关于为啥双重否定强制值成为布尔值?的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin Forms - 否定布尔绑定值

如何在 Python 中获得布尔值的相反(否定)?

JavaScript 中没有额外的布尔类型转换

csharp 使用否定运算符返回布尔表达式的相反值。

csharp 使用否定运算符返回布尔表达式的相反值。

与布尔值 false 进行比较时,如何防止 Linq2Sql 否定位列?