我在C#中使用了一个与符号(&)来表示“检查第二个条件语句,即使第一个条件语句是false”。
但是下面似乎是&
的一个不同的含义,有人能解释一下i & 1
在下面的例子中是如何工作的吗?
List<int> scores = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8 };
var evenScores = scores.Where(i => i % 2 == 0);
var evenScores2 = scores.Where(i => (i & 1) == 0);
6条答案
按热度按时间kfgdxczn1#
一个&是“按位AND运算符”,就像dove说的那样。我正在看问题的第二部分:“为什么它会起作用?”
用binary来思考:
注意所有偶数都以0结尾;因此,如果针对1的最后一位逐位检查返回零(意味着“不匹配”),则其为偶数;
up9lanfz2#
Here:
一元
& operator
返回其操作数的地址(需要unsafe
上下文)。二进制
& operators
是为整型和bool预定义的。对于整型,&
计算其操作数的逻辑逐位AND
。对于bool操作数,&
计算其操作数的逻辑AND
;也就是说,当且仅当它的两个操作数都为真时,结果为真。& operator
计算两个运算符,而不管第一个运算符的值如何。jyztefdp3#
之前的答案是正确的,但没有解决
&
与&&
的区别,我认为这是你最初的问题,所以我会接受这个问题。如前所述,
&
是按位AND。&&
是逻辑AND。&
对其操作数逐位执行AND运算,并且通常功能与+
或*
或任何算术运算符完全相同。&&
更复杂。它将其每个操作数与零进行比较。如果第一个操作数为零,则&
将其操作数与零进行比较。它假定值false
并短路表达式的其余部分,即它不评估任何剩余的操作数。如果第一个值非零,则它检查第二个值。如果这是零,则它假定值false
,否则它假定值true
。在任何一种情况下,它继续对表达式求值。也就是说,
&
和&&
之间有两个关键的区别:&
逐位运算,而&&
只考虑零和非零,总是返回0或1。因此5 & 6
(二进制101 & 110
)给出4(二进制100
),而5 && 6
给出1(true
)。&&
“shortcircuits”。如果第一个值为零,它不会计算第二个值。&
没有这样的规则。这在几个方面很重要:1.如果第二个值有任何副作用,那么对于
&
,这些副作用总是发生,而对于&&
,它们不会发生。因此x & (y++)
将始终递增y
,而x && (y++)
只会在x
不为零时递增y
。如果第二个操作数是函数调用。1.第一个值可能会测试一些东西,确定第二个值是无效的。比如
x!=NULL && x->foo==3
。对于&
,当x
是null
时,可能会出现段错误或等效错误。1.最后,可能会有重要的性能提升。比如,
x!='A' && readTonsOfStuffFromDatabaseAndCalculateTotal(x)
。使用&
,无论如何都会进行读取,而且可能完全是浪费时间。这就是为什么我们几乎总是使用
&&
来处理真正的逻辑操作,并将&
的使用限制在我们真正需要按位操作的时候。但是有时候你不希望短路发生,在这种情况下&
可能是一个不错的选择。但是如果你用它来“逻辑”操作,要非常小心操作数可以有任何值以外的0或1。1 && 2
是true
,但1 & 2
是false
。lp0sw83n4#
对于布尔类型,你提到的是它的行为方式。
对于整数类型,它是按位“与”运算符。
它可以为其他类型重载。
基本上,表达式
(i & 1) == 0
检查i
的最低有效位是否被设置,这仅在数字为奇数时发生。yvfmudvl5#
与号表示按位AND运算。按位运算符返回两个操作数中每个相应位的比较结果。
例如,如果x是0110,y是1010,则x和y的按位AND(x & y)结果是0010。
ql3eal8s6#
按位AND运算符。