C# &&;=和| |=运算符
可能的重复项:C# &&;=和| |=运算符,c#,c++,c,logical-operators,C#,C++,C,Logical Operators,可能的重复项: 今天在工作中,我写了以下LOC(b和b1的真实身份是保密的:) 我盯着它看了几秒钟,意识到根本不存在这样的操作员。为了确定这一点,我点击了compile,结果失败了。可以肯定的是,我参考了标准 是否有具体原因导致没有此类运营商?我能想到一些: b&&=b1和b=b&&b1可能不等效,因为对&&&进行短路评估 &&他很丑 &&=很少需要 我并不认为拥有这样的运营商会非常有用,不。我也不认为上述三个原因中的任何一个或全部都不足以避免创建该运营商。我的问题是:我监督的原因是否更为严
今天在工作中,我写了以下LOC(b和b1的真实身份是保密的:) 我盯着它看了几秒钟,意识到根本不存在这样的操作员。为了确定这一点,我点击了compile,结果失败了。可以肯定的是,我参考了标准 是否有具体原因导致没有此类运营商?我能想到一些:
b&&=b1
和b=b&&b1
可能不等效,因为对&&&进行短路评估我并不认为拥有这样的运营商会非常有用,不。我也不认为上述三个原因中的任何一个或全部都不足以避免创建该运营商。我的问题是:我监督的原因是否更为严重?编辑:语言错误,但仍然适用 我同意您的三个理由,尽管在编写自定义反序列化例程时,有一种情况下我对缺少此运算符表示遗憾。在一些不正确序列化的对象不是真正“异常”的情况下(为了防止C#中非常常见的故障导致异常开销),我会使用布尔返回值来表示反序列化操作是否成功 此代码完全是理论代码,Nested1、Nested2和Nested3都是结构:
public struct ComplexStruct
{
private Nested1 nested1;
private Nested2 nested2;
private Nested3[] nested3;
public bool Read(Reader reader)
{
bool ret = true;
int nested3Length = 0;
ret &&= nested1.Read(reader);
ret &&= nested2.Read(reader);
ret &&= reader.ReadInt32(ref nested3Length);
for(int i = 0; (ret && i < nested3Length); i++)
{
ret &&= nested3[i].Read(reader);
}
return ret;
}
}
public struct ComplexStruct
{
私有嵌套1嵌套1;
私有嵌套2嵌套2;
私有嵌套3[]嵌套3;
公共bool Read(读卡器)
{
bool-ret=真;
int nested3Length=0;
ret&&=nested1.Read(读卡器);
ret&&=nested2.Read(读卡器);
ret&&=reader.ReadInt32(参考嵌套3长度);
对于(int i=0;(ret&&i
我以前也想要它们。我怀疑丑陋本身就是决定因素,短路行为是迄今为止我听到的反对它们的最好论据
另一个影响因素是C设计为在金属附近运行,几乎所有的运算符都直接对应于主要体系结构中的指令。我认为x86、PPC等上没有直接实现
b&&=b1的指令代码>就个人而言,我会投票支持你的第一个理由。布尔运算符具有短路语义,如果将其转换为符号运算符,则会出现一些非常棘手的情况。要么你不再让它们短路,要么你创建了一些奇怪的“可选”赋值运算符(只在LHS上的值已经非零时才执行右边的操作并在结果中赋值)。无论哪种方式,你都会产生微妙的bug,因为人们会期待其他行为。运营商不存在的最大原因可能是K&R没有想到任何吸引人的方式来定义它们。有时我还需要一个->=操作符(ptr->=next相当于ptr=ptr->随便什么)
我认为&&=的一个问题是,不清楚以下哪项最有用,或者应该是什么:
if (lhs && rhs) lhs = 1; else lhs = 0;
if (!rhs) lhs = 0; else lhs = !(!lhs));
if (lhs && !rhs) lhs = 0;
if (!rhs) lhs = 0;
如果(左侧和右侧)左侧=1;否则lhs=0;
如果(!rhs)lhs=0;否则lhs=!(!lhs));
如果(lhs&&!rhs)lhs=0;
如果(!rhs)lhs=0;
第一种变体是语法中最清晰的一种变体,但从实用的角度来看,如果两个术语都不是零,那么将左侧单独保留比将其设置为“1”更有用
顺便说一句,我经常希望使用逗号运算符的变体,它将计算左侧,保存值,然后计算右侧,然后返回左侧的值。相当于:
int foo(int p1, int p2) return p1;
int foo(int p1,int p2)返回p1;
除非适用于任何类型(p2不必与p1相同,可能无效),且具有保证的从左到右的评估顺序。对于非单位步长的增量后索引,例如arr[ptr~,ptr+=2],非常方便;或者对于某些类型的数据交换操作,例如,var1=(var2~,var2=var1);等等。我不知道为什么问题和一些答案都提到相应逻辑运算符的短路行为是一个潜在问题
定义&&
和|124;=
运算符绝对没有与短路相关的问题。它们应该用+=
和其他类似的运算符统一定义,这意味着a&&=b
应该等同于a=a&&b
,但是a
在&&=/code>版本中只计算一次。这意味着如果a
最初为零,则根本不计算b
。简单
因此,它们不存在于语言中的唯一原因是,“仅仅因为”因为a和&b
的结果总是0
或1
,我认为对这一点的解释只有对C99\u Bool
类型而言才是明确的。由于在创建C时该运算符不存在,因此不包括该运算符。现在没有人会轻易地在C中添加另一个操作符,因为这会对所有现有的解析器产生影响。好吧,当我需要它(循环部分)时,这几乎是相同的场景。现在我将编辑我的问题,以澄清在这种情况下,您可以返回false代码>早。酷。。。在我的例子中,我想要短路行为,所以我在大多数情况下使用ret=ret&&xxx。。。这有点冗长,但至少它清楚地表明我正在进行短路布尔比较b&=isSomethingWithSideEffects()
将无论如何运行该函数。但是如果它被更改为&&=
,在b为假的情况下,它可能不会,不是吗?对不起,我不明白为什么野狗的评论是h
int foo(int p1, int p2) return p1;