return !!myVar 是什么意思?
What does return !!myVar mean?
我正在阅读一个使用 glib 的 C 语言的开放代码,我发现了类似这样的东西
gboolean function()
{
guint myVar = 0;
myVar = (!!globalVar1 + !!globalVar2 + !!globalVar3);
return !!myVar;
}
我不明白那个双感叹号到底是怎么回事。
和一个感叹号一样,两次。它两次否定一个值。
这具有将所有整数转换为 0
(如果它们已经是 0
)或 1
(如果它们是任何非零值)
一元 !
运算符执行逻辑 NOT 运算。如果其操作数不为零,则计算结果为 0。如果其操作数为 0,则计算结果为 1。
当它们两个像这样放在一起时,它将操作数规范化为布尔值。因此,如果操作数为 0,则结果为 0,如果操作数为非零,则结果为 1。
在较大表达式的上下文中:
myVar = (!!globalVar1 + !!globalVar2 + !!globalVar3);
这会将 myVar
设置为 0 到 3 之间的值。然后是:
return !!myVar;
将该值标准化为 0 或 1。因此最终结果是,如果 3 个变量中的任何一个不为零,则返回 1,否则返回 0。
函数体可以重写为:
return globalVar1 || globalVar2 || globalVar3;
哪个更清楚地表达了意图。然而,||
运算符确实涉及分支,因此编写的代码可能试图避免该分支。
虽然一般来说,编译器非常擅长优化,所以这样的微优化并不是真正必要的。
让我们首先考虑一下这个说法
myVar = (!!globalVar1 + !!globalVar2 + !!globalVar3);
现在根据 C 标准(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)
例如
如果你有这样的变量
int x = 10;
然后将运算符!
应用到变量!x
你会得到0.第二次应用运算符!!x
你会得到1.如果写是一样的x != 0
.
因此,如果操作数 globalVar1
、globalVar2
和 globalVar3
中至少有一个,则赋值结果为非零值。不等于 0.
上面的语句可以改写成下面的方式
myVar = ( ( globalVar1 != 0 ) + ( globalVar2 != 0 ) + ( globalVar3 != 0 ) );
赋值的结果可以是0(如果所有操作数都等于0),或者1(如果只有一个操作数不等于0),或者2(如果两个操作数都等于0),或者3(如果所有操作数都等于 0)。
如果至少一个操作数不等于 0 或 1,则函数需要 return1。否则
你可以只写在return声明
return myVar != 0;
但是代码的作者决定写
return !!myVar;
看来他很喜欢否定运算符!
.:)
这种使用否定运算符的“平衡行为”的目的是 return 恰好是 0 或 1。
如果 val
为零,!!val
给出 0
,如果 val
不为零,则 1
。
用法示例:
//function counting non zero elelemnts of array
size_t countNonZero(const int *array, size_t size)
{
size_t count = 0;
while(size--)
count += !!*array++;
return count;
}
在您的示例中,不需要 !!
运算符,因为在 C 中任何非零值都被视为 true
。应该使用简单的 ||
运算符。
该函数应重写为
gboolean function()
{
return globalVar1 || globalVar2 || globalVar3;
}
我正在阅读一个使用 glib 的 C 语言的开放代码,我发现了类似这样的东西
gboolean function()
{
guint myVar = 0;
myVar = (!!globalVar1 + !!globalVar2 + !!globalVar3);
return !!myVar;
}
我不明白那个双感叹号到底是怎么回事。
和一个感叹号一样,两次。它两次否定一个值。
这具有将所有整数转换为 0
(如果它们已经是 0
)或 1
(如果它们是任何非零值)
一元 !
运算符执行逻辑 NOT 运算。如果其操作数不为零,则计算结果为 0。如果其操作数为 0,则计算结果为 1。
当它们两个像这样放在一起时,它将操作数规范化为布尔值。因此,如果操作数为 0,则结果为 0,如果操作数为非零,则结果为 1。
在较大表达式的上下文中:
myVar = (!!globalVar1 + !!globalVar2 + !!globalVar3);
这会将 myVar
设置为 0 到 3 之间的值。然后是:
return !!myVar;
将该值标准化为 0 或 1。因此最终结果是,如果 3 个变量中的任何一个不为零,则返回 1,否则返回 0。
函数体可以重写为:
return globalVar1 || globalVar2 || globalVar3;
哪个更清楚地表达了意图。然而,||
运算符确实涉及分支,因此编写的代码可能试图避免该分支。
虽然一般来说,编译器非常擅长优化,所以这样的微优化并不是真正必要的。
让我们首先考虑一下这个说法
myVar = (!!globalVar1 + !!globalVar2 + !!globalVar3);
现在根据 C 标准(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)
例如 如果你有这样的变量
int x = 10;
然后将运算符!
应用到变量!x
你会得到0.第二次应用运算符!!x
你会得到1.如果写是一样的x != 0
.
因此,如果操作数 globalVar1
、globalVar2
和 globalVar3
中至少有一个,则赋值结果为非零值。不等于 0.
上面的语句可以改写成下面的方式
myVar = ( ( globalVar1 != 0 ) + ( globalVar2 != 0 ) + ( globalVar3 != 0 ) );
赋值的结果可以是0(如果所有操作数都等于0),或者1(如果只有一个操作数不等于0),或者2(如果两个操作数都等于0),或者3(如果所有操作数都等于 0)。
如果至少一个操作数不等于 0 或 1,则函数需要 return1。否则
你可以只写在return声明
return myVar != 0;
但是代码的作者决定写
return !!myVar;
看来他很喜欢否定运算符!
.:)
这种使用否定运算符的“平衡行为”的目的是 return 恰好是 0 或 1。
val
为零,!!val
给出 0
,如果 val
不为零,则 1
。
用法示例:
//function counting non zero elelemnts of array
size_t countNonZero(const int *array, size_t size)
{
size_t count = 0;
while(size--)
count += !!*array++;
return count;
}
在您的示例中,不需要 !!
运算符,因为在 C 中任何非零值都被视为 true
。应该使用简单的 ||
运算符。
该函数应重写为
gboolean function()
{
return globalVar1 || globalVar2 || globalVar3;
}