假设我的布尔条件为a AND b OR c AND d,并且我使用的语言中,AND的操作先例比OR的操作先后顺序高。我可以编写以下代码行:

If (a AND b) OR (c AND d) Then ...


但是实际上,这等效于:是否有赞成或反对包括多余括号的论点?实践经验是否表明值得将它们包括在内以提高可读性?还是表明开发人员需要真正坐下来并对他们的语言基础充满信心?

评论

我可能会很懒,但是为了提高可读性,我更喜欢在大多数情况下使用括号。

我也是。我只是希望我为提高可读性而少做些事情,因为我懒得对我的语言基础变得自信/称职。
正确使用括号就像正确使用语法一样。 2 * 3 + 2可能与(2 * 3)+ 2相同,但第二个字母更易于阅读。

@Mathew如果您的数学能力不强,也许会。对于更复杂的情况,请确保使用括号。但是对于盲目的明显的对象(BODMAS…),由于杂乱,它们的可读性要比辅助它降低更多。

就是说,AND / OR在Basic,Python,SQL中具有相同的优先级。我的印象是,这是绝大多数现代语言(尽管不是全部)中的规则。

#1 楼

优秀的开发人员努力编写清晰,正确的代码。

为了清楚起见,请想到括号,就像代码中的注释:并不是严格必须的,理论上有能力的开发人员应该能够找出没有它们的代码。但是,这些提示非常有用,因为:


它们减少了理解代码所需的工作。
它们可确认开发人员的意图。

此外,多余的括号(如缩进,空格和其他样式标准)有助于以直观的方式直观地组织代码。 。当它们发生时,它们可能是很难发现的错误-因为通常情况下,错误的条件在大多数情况下都会正确执行,并且偶尔会失败。下一个处理您的代码的人可能不会,要么在表达式中添加错误,要么误解您的逻辑,从而在其他地方添加错误(正如LarsH正确指出的那样)。

我始终对包含and的表达式使用括​​号和or(以及具有类似优先级问题的算术运算)。

评论


虽然,我听说它说注释是道歉的(对于不好的/难读的代码)……您很有可能可以更好地编写它。我想您可以对括号说类似的话。

–杰夫B
13年6月11日在21:05

正确性的另一个方面是通过更改来保持正确性:尽管最初的开发人员在首次编写代码时就牢记了优先权,但没有括号,但他(或另一个)后来出现了,他不记得所有当它们在表达式中添加更多术语时,这些细节很可能将其弄乱。 (这已经隐含了很多,但是我觉得值得强调。)

– LarsH
2013年6月12日13:33



@LarsH,谢谢,我将其明确添加到了答案中。

–user82096
2013年6月12日13:36

+1“他们提供对开发者意图的确认。” -任何程序员(可以,也许不是全部,但是所有驻留在这里的人..)都可以计算出编译器将使用最复杂的逻辑做什么。绝对没有人能在最初几周的时间里弄清原始开发人员的意图(包括他自己),以解决最简单的事情。

–mattnz
2013年6月14日下午3:24

我认为@JeffBridgman引用了一个众所周知的观点,即“注释有时可能是代码的味道”。例如。请参阅Jeff Atwood的摘要,其中包括问题“您是否可以重构代码,因此不需要注释?”。我认为,如果您的评论解释了为什么您的代码如此不直观,那肯定可以暗示出问题了。在这种情况下,简化代码是个好主意。我完全同意您的实际答案,但是请加上括号。

–丹尼尔B
13年6月14日在11:18

#2 楼

是否对掌握语言有信心就无关紧要。更重要的是掌握紧随您的n00b语言。

以最清晰,最明确的方式编写代码。多余的括号通常(但不总是)有帮助。在一行上仅放置一条语句通常会有所帮助。编码风格的一致性通常会有所帮助。

括号太多了,但这是您不需要建议的情况之一-当您看到时就会知道。此时,重构代码以减少语句的复杂性,而不是删除括号。

评论


即使您是生病,疲倦或处理去年编写的代码的单独开发人员,也请不要忘记。您的理解水平将降至n00b。

–丹在火光中摆弄
13年6月11日在16:01

括号太多了-您显然不是傻子;)

–保罗
13年6月11日在17:12

不好的建议:不要为菜鸟写东西。这会(一定程度上)降低代码质量,因为您不能使用超出初学者书籍前两章的公认习语。

–康拉德·鲁道夫(Konrad Rudolph)
2013年6月11日在21:41



@KonradRudolph:也许是这样,但不要写那些只从头到尾了解计算机编程艺术的人,或者不准备在以后调试其代码,却不知道为什么要这样做的线索的人。阅读的代码远不止编写代码。

– Haylem
2013年6月11日23:20

@dodgethesteamroller:我已经看到太多能干/受人尊敬的开发人员引入了优先级错误(每个人都时不时地糟糕),这些错误多年来一直没有被注意到。对于确实了解优先规则的优秀开发人员,未检测到的错误/错别字的风险太大。对于其他所有人,风险更高。最好的开发人员是那些曾经记住该语言的优先级规则的开发人员,但是由于习惯性地将括号用于任何不明显的事物而忘记了它们的优先级。

–布伦丹
2013年6月12日下午5:09

#3 楼

是的

您应该始终使用括号...您不控制优先顺序...编译器的开发人员可以。这是我发生的一个不使用括号的故事。这在两周内影响了数百人。

现实世界的原因

我继承了一个大型机应用程序。有一天,它突然失去作用了。就这样......声就停止了。

我的工作是使它尽快运行。源代码已经有两年没有修改了,但是突然间它就停止了。我试图编译代码,但它在第XX行中断了。我看着XX行,但我不知道是什么使XX行中断。我询问了此应用程序的详细规格,但没有任何规格。 XX行不是罪魁祸首。

我打印了代码并开始从上至下进行检查。我开始创建正在发生的事情的流程图。代码太复杂了,我什至无法理解。我放弃尝试绘制流程图。我很害怕做出更改,却不知道该更改将如何影响其余的过程,尤其是因为我没有应用程序的功能或依赖链中的位置的详细信息。决定从源代码的顶部开始,并添加whitespce和行制动器,以使代码更具可读性。我注意到,在某些情况下,是否存在将ANDOR组合在一起的条件,并且在区分AND ed和OR ed是什么数据之间并不清楚。因此,我开始在ANDOR条件周围加上括号,以使其更具可读性。

当我慢慢进行清理时,我会定期保存工作。有一次我尝试编译代码,然后发生了一件奇怪的事情。该错误已跳过了原始代码行,而现在进一步降低了。所以我继续,用括号分隔了ANDOR条件。当我完成清理工作时。去看图。

然后我决定去操作车间,问问他们最近是否在主机上安装了新组件。他们说是的,我们最近升级了编译器。嗯。

事实证明,旧的编译器无论如何都从左到右评估表达式。新版本的编译器还从左到右评估表达式,但代码含糊不清,这意味着无法解决ANDOR的不清楚的组合。当结合使用AND条件和OR条件时,请使用括号将它们分隔开。这是我遇到的问题的简化版本。复合布尔逻辑语句还存在其他条件。原始作者早已不复存在。我记得压力很大。一整艘货船被困在港口,无法卸载,因为这个小程序不起作用。没有警告。无需更改源代码。在我发现添加括号改变了错误之后,我才问网络运营商是否修改了任何内容。

评论


这似乎更好地说明了为什么拥有一个好的编译器很重要。

–ruakh
2013年6月11日19:35

@CapeCodGunny:我确定你没有。但是这里的问题是您的编译器供应商不好,并且做出了重大更改。即使您使用更好的编译器,我也看不到您如何从“总是,总是,总是”上解决该问题的课程。

–ruakh
13年6月11日在20:55

@ruakh-不,供应商只是更改了代码解析器。我是一所老学校,我并不依靠自己的能力来记住自己编写或参与的每个系统。没有文档,您所拥有的只是源代码。当难以阅读和遵循源代码时,就会造成极大的压力。不使用空格的程序员可能从未遇到过像我这样的情况。我还了解到编写如下代码更有意义:见简;见迪克和简;易于阅读的简单语句...注释掉并遵循。

– Michael Riley-又名Gunny
2013年6月11日22:06



很棒的故事,但我同意这不是使用括号的原因。和/或优先级几乎是普遍适用的,并且几乎是人们可能想到的最不可能改变的事物。如果您不能依靠一致的行为来执行这种标准的基本操作,则您的编译器将成为垃圾,无论您做什么都将被束之高阁。您的故事是100%的编译器问题和0%的代码问题。尤其是考虑到默认行为是简单的从左到右求值-顺序总是很清楚,那么为什么有人会使用括号呢?

–user82096
13年6月12日在12:54

我认为双方都有经验教训……最好使用括号,特别是当替代方法依赖于编译器针对歧义代码的无证行为时。而且,如果程序员不知道哪些表达式是模棱两可的,最好使用parens。另一方面,更改编译器的行为很危险,但是至少在行为更改的情况下会引发错误。如果编译器没有引发错误,而是开始以不同的方式进行编译,那就更糟了。该错误保护您免受未发现的错误的侵害。

– LarsH
2013年6月12日13:38



#4 楼

是的,如果混合使用“和”和“或”。

()逻辑上是一种检查也是个好主意。可读。

评论


的确,很可能将AND b替换为具有更描述性名称的函数或预先计算的布尔值。

–杰夫B
2013年6月11日14:30在

#5 楼

括号在语义上是多余的,因此编译器不在乎,但这是一个红色的鲱鱼-真正关心的是程序员的可读性和理解力。对a AND b OR c AND d中的括号表示衷心的“否”。每个程序员都应该从心底知道布尔表达式的优先级不是NOT AND AND OR,就像记住“请为我亲爱的萨莉姨妈萨莉”代数表达式一样。多余的标点符号大多数时候只会在代码中增加视觉混乱,而对程序员的可读性没有好处。标记为“这里发生了一些棘手的事情-注意!”就是说,在您要覆盖默认优先级并在乘法运算之前或在与运算符AND之间进行加法运算的情况下,括号对于下一个程序员而言是一个不错的警示。当不需要它们时,过多地使用它们,您便成为了《狼来了的男孩》。 C语言中的表达式,其中比标准习惯用法(例如*p++p = p->next)更复杂的任何事物都应该加括号以保持解引用和直接的运算。而且,当然,这都不适用于使用某种形式的波兰语表示法的Lisp,Forth或Smalltalk等语言。但是对于大多数主流语言,逻辑和算术优先级是完全标准化的。

评论


+1,为了清楚起见,括号是可以的,但是AND vs OR是一个相当基本的情况,我希望团队中的其他开发人员都知道。我担心有时“使用括号以清楚起见”实际上是“使用括号,因此我不必费心学习优先级”。

–蒂姆·古德曼(Tim Goodman)
2013年6月12日13:40

在我使用的所有语言中,它通常是.member在一元运算符之前,一元运算符在二进制运算符之前,*和/之前+和-之前<和>以及==之前&&之前||之前在分配之前。这些规则很容易记住,因为它们符合我对正常使用运算符的“常识”(例如,您不会给==优先于+或1 + 1 == 2停止工作),并且涵盖95我要优先考虑的问题的百分比。

–蒂姆·古德曼(Tim Goodman)
13年6月12日在13:48

@TimGoodman是的,完全正确,您的评论都对。这里的其他响应者似乎认为这是一个黑人或白人问题-要么一直使用括号,没有例外,要么通过随意且难以记住的规则之海在裤子的座位上漫不经心地飞翔,代码泛滥成灾以及潜在的难以发现的错误。 (混合的隐喻非常有意。)显然,正确的方法是节制。代码的清晰性很重要,但是对您的工具的了解也很重要,您应该能够从团队成员那里获得对编程和CS原理的某种最低程度的了解。

–dodgethesteamroller
2013年6月12日19:57



#6 楼

据我所知:

是优点:


操作顺序是明确的。操作。

是缺点:


可能会导致混乱,难以阅读的代码

否优点:


?操作顺序。


评论


说得好,尽管我认为“可能导致混乱,难以阅读的代码”相当主观。

– FrustratedWithFormsDesigner
2013年6月11日14:42



如何使代码的语义明确,使其难以阅读?

–梅森·惠勒
2013年6月11日14:44

我同意其他人对您“同意”的质疑。我认为几乎总是相反。

–user82096
2013年6月11日14:56

@沮丧与相反的主张一样主观。的意思,一点也不是真的。很难衡量。

–康拉德·鲁道夫(Konrad Rudolph)
2013年6月11日21:40在

@MasonWheeler:尽管我同意显式括号在许多情况下非常重要,但我可以看到人们如何过分强调语义。我发现3 * a ^ 2 + 2 * b ^ 2比(3 *(a ^ 2))+(2 *(b ^ 2))更容易阅读,因为格式和优先级是熟悉且标准的。同样,您可以(极端)禁止使用函数和宏(或编译器!),以便使代码的语义更明确。显然,我不主张这样做,但我希望回答您的问题,即为什么在使事情明确时需要限制(平衡)。

– LarsH
2013年6月12日13:45

#7 楼


是否有任何论点支持或反对包括多余的括号?实践经验是否表明值得将它们包括在内以提高可读性?还是一个信号,表明开发人员需要真正坐下来并对他们的语言基础充满信心?认为我不会在意。 >其他人有时会看我的代码

,甚至不得不扩展/修复它!
写神秘的“最小化字符数”代码会损害可读性

我几乎总是这样做,因为我相信我的能力能够快速阅读并且不会用小错误犯更多的错误。

就您而言,我几乎可以肯定地做类似的事情:

是的,我可以改做花式布尔运算符。不,我不希望将来再漏读1年以上的代码时会误读一些花哨的bool运算符。如果我用具有不同AND / OR优先级的语言编写代码并且不得不跳回以解决此问题怎么办?我要走了吗,“啊哈!我还记得我所做的这个聪明的小事!去年写这篇文章时,我不必包括parens,现在我还记得好事!”如果发生这种情况(或更糟糕的是,其他人不知道这种聪明之处,或者陷入了“尽快修复”类型的情况)?略读并稍后了解...

评论


如果要这样做,为什么不选择ab = a AND b?

–埃里克
2013年6月11日在21:02

也许是因为ab如果不是AND,则ab将保持不变。

– Armali
15年8月7日在6:30

#8 楼

一般情况

在C#中,乘法和除法优先于加法和减法。使用规则SA1407来减少可能不够清晰的代码引入的错误的风险。此规则将使用以下代码产生警告:

var a = 1 + 2 * 3;


很明显,结果是7而不是9,但StyleCop仍然建议加上括号:

var a = 1 + (2 * 3);


您的特定情况

在您的特定情况下,与您使用的特定语言中的OR相比,AND优先。

这不是每种语言的行为方式。

作为一个主要使用C#工作的开发人员,当我第一次看到您的问题并在不阅读您之前编写的内容的情况下阅读代码时,我的第一个诱惑是要评论这两个表达式不相同。希望在评论之前,我已经完整地阅读了整个问题。 />
不要编写旨在表明自己很聪明的代码。编写代码以提高可读性为目标,包括可能不熟悉该语言各个方面的人员。

评论


“这非常罕见”:根据Stroustrup2013,C ++ 11似乎具有不同的AND和OR优先级(第257页)。与Python相同:docs.python.org/2/reference/expressions.html

–德克
2013年6月11日19:26



回复:“我知道的每一种语言都将AND和OR等同对待”:我怀疑这是真的。如果是真的,那么您就不知道十种最受欢迎​​的语言(C,Java,C ++,PHP,JavaScript,Python,C#,Perl,SQL和Ruby)中的任何一种,并且无法发表评论什么是“罕见”,更不用说“非常罕见”了。

–ruakh
2013年6月11日19:34

我同意ruakh并在C ++ 11,python,matlab和java中查找它。

–德克
2013年6月11日19:36

其中AND和OR为二进制运算符,并且不将AND的优先级视为比OR高的语言,是被人为破坏的胡言乱语,其作者是计算机科学的笨拙人士。这来自逻辑符号。你好,“产品总和”不代表什么吗?甚至有一个布尔符号,它对AND使用乘法(因子的并置),对OR使用+符号。

–卡兹
2013年6月12日7:53

@ruakh你只是为我讲了观点。因为存在一些病理性边缘情况,并不意味着您不应该学习标准的布尔优先级,并假设它成立,直到得到另外证明。我们这里不是在谈论任意的设计决策;布尔代数早于计算机而被发明。另外,请告诉我您正在谈论的Pascal规格。在此处和此处在OR之前显示AND。

–dodgethesteamroller
2013年6月12日19:51



#9 楼

众所周知,每次使用括号都会使表达式更具可读性。但是,如果表达式很复杂,建议您为子表达式引入新功能。

#10 楼


还是标志着开发人员需要真正坐下来对他们的语言基础充满信心?


如果严格使用单数语言, 也许。现在,使用所有您知道的语言,从古老到现代,从编译到脚本编写,再到SQL,再到您上个月发明的自己的DSL。

您还记得每种语言的确切优先级规则这些语言,不用看?

评论


就像@Cape Cod Gunny上面指出的那样,即使您认为自己的语言很冷,编译器/运行时也可能在您以下改变。

–乔丹
2013年6月11日19:26

#11 楼

“即使在不必要的情况下,我也应该在逻辑语句中使用括号。”

是的,因为两个人会发现它们很有用: ,能力或风格可能有所不同
以后您将来再使用此代码的将来!


#12 楼

复杂的条件词是“布尔代数”,您可以通过某种方式编写它们,使其看起来非常像代数,而您肯定会使用parens代数,对吗?真正有用的规则是取反规则:

!(A || B) <=> !A && !B
!(A && B) <=> !A || !B


,或者,以更清晰的格式:
>这显然是代数,写为:

尽管必须在代码中编写:

!(A + B) <=> !A * !B
!(A * B) <=> !A + !B


,或者,以更清晰的格式:

基本上,条件表达式仍然只是代数表达式,通过清楚地使用括号,您可以更轻松地将已知的各种代数规则应用于表达式,包括“简化或扩展这个公式”。

评论


我不确定您实际上是在回答这个问题,因为您以不一定是正确的假设来领导您的答案。我会用括号代数吗?并非一直如此。如果它有助于提高可读性,那么可以肯定,但是其他人已经在这里表达了这一点。而且将数学代数扩展为其他形式与编程并不完全一一对应-如果要检查几个字符串值的状态该怎么办?

–德里克
2013年6月11日19:46

如果相应的布尔代数足够复杂以允许使用括号,则您的条件运算可能应该使用括号。如果它很简单,不需要担保,那么您要么不必,要么不应该。无论哪种方式,都可以像对待数学表达式一样思考它,从而可以解决问题。

– Nafanator
13年6月11日在20:09

我上面的示例使用两个和四个布尔值。如果要检查两个或多个字符串值的状态,它将映射。每个检查对应一个布尔变量;不管该检查是整数还是字符串相等;字符串,数组或哈希包含;一个复杂的表达式本身...没关系;重要的是,您在表达式中有不止一种对/错的度量。

– Nafanator
2013年6月11日20:13在

只是挑剔,但在!(A + B)<=>!A +!B和-1 *(A + B)= -A + -B中,运算符不应该在第二个表达式中从+转换为* ?

–杰夫B
13年6月11日在21:18

#13 楼

即使括号是可选的,我也将使用括号,这是为什么,因为它有助于更​​好地为每个人,编写代码的人和准备看该代码的人理解。在您的情况下,即使布尔运算符也具有优先权,但一开始它可能会运行良好,但是我们不能说它会在每种情况下都对您有所帮助。因此我更喜欢在可能需要或可能需要的任何情况下使用括号。

#14 楼

是。在任何情况下,当您认为自己的代码会更清晰时,都应该使用。请记住,您的代码应该足够清晰,以便其他人可以理解而无需阅读代码内部的注释。因此,使用括号和花括号是一个好习惯。还请记住,这可能取决于您的公司/团队的特定实践。只需保持一种方法,不要混淆。