3

我正在尝试检查是否有任何位int x等于 1,答案是!!x。我用谷歌搜索了一下,没有找到任何关于为什么这是正确的。

所以说如果我有一个数字x1010。会!x是什么?!x和有什么区别~x

4

5 回答 5

5

!是一个逻辑运算符,它采用标量类型的操作数的

引用C11,第 6.5.3.3 章,一元算术运算符

如果其操作数的值比较不等于 0,则逻辑否定运算符的结果!为 0,如果其操作数的值比较等于 0,则为 1。结果类型为int。[...]

OTOH,~是一个按位运算符,它对整数类型的操作数执行按位否定。

有关的,

运算符的结果~是其(提升的)操作数的按位补码(即,当且仅当未设置转换操作数中的相应位时,结果中的每个位都被设置)。整数提升在操作数上执行,结果具有提升的类型。[...]

例如,考虑二进制数10

  • !100
  • ~1001

编辑:

FWIW, is you use !!, 你能得到的结果是 0 或 1. OTOH, is you use ~~, 你取回操作数的原始值。

于 2016-02-04T15:40:05.047 回答
1

我正在尝试检查 int x 是否有任何位等于 1,答案是!!x[...]

不,“答案”(即用 C 编写此检查的正确方法)是简单的x != 0. 这更清楚,不会让读者思考。使用两个逻辑反转计算相同的值,但不太清楚。

引用 C11 规范草案,我们有:

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

所以,其实并没有什么区别。

此外,关于负零,该标准要求

对于任何整数类型,所有位都为零的对象表示应是该类型中值零的表示。

因此,检查整数的“所有位为零”实际上与比较(不等于)0 相同。

于 2016-02-04T16:17:02.703 回答
1

的可能值的范围!x是 0 和 1。

~(按位补码)与其域具有相同的范围。

所以~~x会恢复x,但!!x不一定会那样做。

于 2016-02-04T15:42:17.817 回答
0

: 是一个逻辑运算符,它在操作时只给出作为结果。它将true转换为false并将false转换为true
~ : 是一个按位否定运算符,即如果某个值的特定位为 0,它将将该位翻转为 1,反之亦然。请注意,它不对整个值进行操作,它仅对位进行操作。

在 C 语言中,只有数值 0(即 1 字节二进制等效值:00000000)在逻辑上是false,其他一切都是true。任何在其二进制等效项中即使有一个位等于 1 的值都是正确的。所以,

/*Use and explanation of !x*/

int x = 1; //binary equivalent: 00000001 is logically true. it can be checked as follows
if (x) // if statement coerces x to boolean equivalent which is true.
    printf("%d is true", x);

上面代码片段中 的printf语句将被执行。

现在,当在 x (即!x)上使用非逻辑运算符时,结果为false,因为 x ( =1 ) 在逻辑上为true。使用它两次(即!!x)将使它再次成为现实
注意:第一次使用它会导致两件事

  1. 导致值 1 的类型转换为等效布尔值(即true)。
  2. 将布尔值(从步骤 1)更改为相反的值(即false)。

因此,基本上非逻辑运算符可用于检查某事是真还是假。使用它两次返回与被检查值等效的实际布尔值。

/*Use case of ~x (bit-wise negation operator)*/
int x = 1; //binary equivalent: 00000001
int y = ~x; //Now, y will be ~x i.e. 11111110. it can be checked as follows.

printf("%d: value after operation of bit-wise operator", y);
//The printf statement will print decimal equivalent of 11111110 i.e. -2.

y = ~y; // i.e. y = ~~x, this will again flip the bits and make y equal to 1 i.e. 00000001.
printf("%d: value after double operation of bit-wise operator", y);

因此,当需要检查某个值中的任何位是否为 1 时,基本上意味着检查该值在逻辑上是否为。这可以使用 if 语句(如上所示)或使用偶数个逻辑非运算符来检查,如下所示

int x = 1;
if(!!x)
  printf("x is true");
于 2016-03-12T02:04:28.873 回答
-1

C 中的 NOT 逻辑运算由运算符 表示!
在 C 中,每个值都意味着FALSE(如 0、0.0 或空指针常量NULL)。OTOH,每个非空都被认为是TRUE
逻辑否定对逻辑值进行取反,从而将整数值 0 中的每个非零值转换为整数值 1,并将整数值 1 中的每个零值转换。
那么,双重否定只能是 0 或 1。

现在,如果一个对象表示一个算术值,当且仅当该值是 0 或 0.0 时,它的所有位都是 0。所以这样一个对象的否定等于!0,也就是1。另外,如果像10101010这样位不全为0的对象只是一个非空值,那么它的否定就是0(即!10101010 == 0) .

最后,你有!!0 == 0!!(non-zero-value) == 1

C 中的按位否定由运算符 表示~
在这种情况下,对每个分离的位执行否定操作。
例如:~11100111 == 00011000

因此,如果您应用按位否定运算符两次,则恢复原始值: ~~x == x.

于 2016-02-04T15:51:17.360 回答