我经常听到"一切"除了0是真的。但是现在我发生了很奇怪的事情......或者我只是觉得我不是以正确的方式做到这一点。以下是发生的事情:
当我想检查 a 是否等同于 b 时,我可以使用NOT(a XOR b)
。当我检查unsigned char
时,一切正常,例如
unsigned char a = 5;
unsigned char b = 3;
unsigned char c = ~(a^b);
给了我c == 249
:
a 是:00000101
,即5。
b 是:00000011
,即3。
〜(a ^ b)是:11111001
,即249。
现在,让我们试试bool
。
cout << ~(true^true) << ~(true^false) << ~(false^true) << ~(false^false) << endl;
cout << ~(~(true^true)) << ~(~(true^false)) << ~(~(false^true)) << ~(~(false^false)) << endl;
if (~(true^true) == true)
cout << "true";
else
cout << "false";
这让我在控制台中:
-1-2-2-1
0110
false
虽然我预计第一行是:
1001
在问朋友后,他建议我尝试!
而不是~
,看看它是否能正常运作。并且(我认为)它现在正常工作。但我不明白为什么。不应该布尔否定对bool工作吗?
答案 0 :(得分:9)
您误解了算术转换。当您对整数类型的某个表达式~e
说e
时,该值首先会提升为至少 - int
,并且e1 ^ e2
的值相同(对于任何算术表达式) , 对于这个问题)。因此,true ^ true
首先将其操作数提升为int
,产生1 ^ 1
,确实为0,因此您最终得到~0
,在您的平台上{{1} }}
通过将结果转换回-1
:
bool
在你的最后一个问题中,由于你有一个带有std::cout << static_cast<bool>(~(true ^ true))
运算符的表达式,其中两个操作数具有不同的类型,所以两个操作数都被提升为公共类型,这又是==
和{{ 1}}与int
不同。同样,您可以先将两个操作数转换为-1
,以获得所需的相等性。
元课程是C ++中作用于整数的内置运算符实际上仅在1
上运行且更宽,但不在任何较短类型上运行(bool
,int
,bool
)(和类似的考虑适用于通过省略号传递整数)。虽然这有时会引起一些混乱,但我想这也会简化语言规则。这是C ++ C传承的一部分。
答案 1 :(得分:4)
我经常听到&#34;一切&#34;除了0是真的
它对条件有效,例如在if语句中(这里和下面我引用了C ++标准)
作为表达式的条件的值是的值 表达式,上下文转换为bool以外的语句 开关
例如,如果您要写为
if (~(true^true) )
cout << "true";
else
cout << "false";
代替您的代码段
if (~(true^true) == true)
cout << "true";
else
cout << "false";
或使用逻辑否定运算符!
时
9逻辑否定运算符的操作数!在语境上 转换为布尔(第4条);如果转换它的值是真的 操作数是假的,否则是假的。结果的类型是bool
至于运营商==
那么
6如果两个操作数都是算术或枚举类型,则通常 对两个操作数执行算术转换;每一个 如果指定的关系为真,则运算符应为真 如果是假的,则为false。
就是
if (~(true^true) == true)
应用通常的算术转换,即布尔值true转换为整数值1并且它不等于左operanf的表达式,因为左操作数的内部二进制表示不同于1,如第一个输出所示代码段..
答案 2 :(得分:3)
仅考虑您的第一个例子,
~(true^true)
首先,^
的操作数被提升为int
,因此这相当于
~(1^1)
然后xor为1本身产生一个全零位模式,无论int
表示如何表示值0:
~0
这将全零比特模式中的每个比特反转为0,从而产生具有所有比特1的比特模式,例如,对于32位int
,
int( 0xFFFFFFFF )
现在几乎是通用的二元补码形式表示有符号整数,这就是值-1。
因此您的输出
-1
答案 3 :(得分:2)
~
有点不明白。
e.g。对于unsigned char,~0是255,而对于@!true
,则为〜!{/ p>
答案 4 :(得分:2)
逻辑否定和按位否定之间存在差异。按位否定翻转变量中的位,逻辑否定翻转逻辑值,即true / false。考虑例如数字5,以二进制表示为101.如果只翻转位(~5),则会得到11111010,这不是假的,因为在c ++中只有全零为假。但是如果你计算(!5)你会得到全零,这将在一个条件下工作。