逻辑运算符的书面版本

Posted

技术标签:

【中文标题】逻辑运算符的书面版本【英文标题】:The written versions of the logical operators 【发布时间】:2011-01-23 12:04:53 【问题描述】:

This 是我见过的唯一一个andornot 在 C++ 中被列为实际运算符的地方。当我在 NetBeans 中编写一个测试程序时,我得到了红色下划线,好像有语法错误,并认为网站是错误的,但是 NetBeans 是错误的,因为它按预期编译和运行。

我可以看到!not 更受青睐,但and && or 的可读性似乎比它们的语法兄弟要好。为什么存在这些版本的逻辑运算符,为什么似乎没有人使用它?这是真正有效的 C++ 还是语言中包含的与 C 的某种兼容性?

【问题讨论】:

\me 重写他所有的代码 本着“干净代码”的精神,我个人建议改掉写||&& 的习惯,有时甚至是!。文字总是比“线路噪音”好,更不用说可能与位操作运算符混淆了。 @Ichthyo 这并不总是正确的。阅读大量符号并知道它们的含义比阅读大量单词要快得多。 讽刺的是,and 更具可读性,然后写成 "and && or" :) @Ichthyo 你有没有编程过 Fortran?在 Fortran 中,您会得到内心的渴望:几乎所有 C/C++/Java 中的符号都是 Fortran 中的关键字。你会得到beginendcontainspointerallocatableextends 等。如果有人让我再次使用 Fortran,我会朝相反的方向快速奔跑,但是,嘿,也许这是你的任务? ;-) 老实说,在 C/C++/Java 中对重要内容使用符号是一项功能,而不是错误。它可以让您的眼睛快速识别单个符号,而不是解析和解释一个单词。 【参考方案1】:

它们起源于 C 的标头 <iso646.h>。当时有键盘无法键入&& 所需的符号(例如),因此标题包含#define 可以帮助他们这样做,通过(在我们的示例中)定义and成为&&。当然,随着时间的推移,这变得越来越少了。

在 C++ 中,它们变成了所谓的替代标记。您确实不需要包含任何内容以在兼容的编译器中使用这些标记(因此,C 标头的 C++ 化版本 <ciso646> 是空白的)。替代标记就像常规标记一样,除了拼写。所以在解析and的过程中完全&&一样,只是同一个东西的拼写方式不同而已。

至于它们的使用:因为它们很少被使用,使用它们往往比它有用更令人惊讶和困惑。我敢肯定,如果它是正常的,它们会更容易阅读,但人们已经习惯了 &&|| 其他任何东西都会让人分心。

编辑:但是,自从我发布此消息以来,我发现它们的使用量略有增加。我仍然避免他们。

【讨论】:

那么对这些替代标记的解释仅仅是编译器功能还是在 C++ 规范中? @Kavon:在标准的2.5节中有规定;这是一种语言功能。 我个人认为它们要好得多...但是我偏向 Python。我不知道为什么有些人认为如果不是乱码就不是代码...... 所以如果不包含该头文件,这些在 C 中是无效的?我很惊讶这些不是每个人都使用的;它们使 Python 更具可读性。 至少 Visual Studio 2015 CTP 6 不喜欢我的 ornot 而不包括标题。【参考方案2】:

它们确实存在于可用性(键盘/显示器风格中的字符支持)和一般可读性,但还有另一个原因,现在更加明显。几乎没有一个答案here、here,甚至主要答案here 都没有说明我们中的许多人更喜欢单词版本而不是符号版本的核心原因(以及其他语言使用它们的主要原因):错误。单词版本之间的差异非常明显。符号版本之间的差异明显较小,以至于在更大程度上引诱错误:“x|y”与“x||y”非常不同,但当嵌入到更大的表达式中时,我们中的许多人错过差异。它类似于赋值与相等运算符的常见意外混合。出于这个原因,我已经放弃了符号版本(这并不容易),转而支持单词版本。由于我们对旧事物的热爱,我宁愿有人对它们进行双重检查,而不是引诱虫子。

【讨论】:

不幸的是,在 Visual Studio 中(自 VS2013 起),您必须设置特定的编译器选项 (/Za) 才能支持替代关键字(请参阅 ***.com/a/555524/368896)。这大概还有其他影响。因此,在 Visual Studio 中,采纳此建议并不一定安全。 FWIW /- 当我在运算符周围放置空格时,x | y 在视觉上与x || y 有足够的区别(在等宽字体中),但我确实找到了!,例如if (!f(xyz) && ...if (not f(xyz) && ... 更容易错过。 @Tony D 当您在运算符周围放置空格时,这是您的私人约定,对读者来说并不明显。但是在布尔表达式中使用andornot 等自然语言单词实际上提高了可读性,而且它突出了与位操作的区别。因此恕我直言,我们应该考虑将我们心爱的旧习惯改得更好...... 你知道因为andor这两个词会影响人们对它们应该如何工作的想法,因此引入了多少Python错误吗?例如。 if (a == b or c) 而不是 if (a == b || a == c) - *** 上几乎每天都会出现类似的情况。与英语脱节的抽象符号可以减少这些错误。 如果逻辑是基于符号的,您认为人们不太可能滥用运算符优先级吗?我认为这是一个不受逻辑表示方式影响的单独问题......以至于我对绿色 Python 用户(尤其是 Python 是许多人的第一语言)的建议是在他们学习之前只使用括号。但这只是我。具有讽刺意味的是,在我目前专门使用符号的组中,我现在也使用它们。我只需要更加小心,这也是一种有助于优先处理的方法。【参考方案3】:

在 C++ 中,它们是真正的关键字。在 C 中,它们是在 <iso646.h> 中定义的宏。见http://web.archive.org/web/20120123073126/http://www.dinkumware.com/manuals/?manual=compleat&page=iso646.html

【讨论】:

从技术上讲,它们是替代标记,而不是关键字。 :) @GMan:+1 不错的电话,不过,Dinkumware 页面称它们为关键字,所以,我想他们并不太在意区别。 更新链接:f3.tiera.ru/1/addesio/computer-science/C&C++/… @rwst 我无法具体评论 MSVC,但如果它忠实地实现了 C++ 和 C 标准,那么确实会如此。另见:***.com/questions/2376448/… 对于 C 标头,另请参阅 en.cppreference.com/w/c/language/operator_alternative【参考方案4】:

and&& 在 C++ 中的功能相同。 andor 运算符是真正有效的 C++ 和语言标准的一部分。

用一个具体的例子来详细说明其他答案,除了“可读性”之外,还有另一个原因是更喜欢and 而不是&&。当逻辑 AND 是您的意思时,明确拼写“and”可以消除细微错误的可能性。

考虑一下:

int x = 3;
int y = 4;

// Explicitly use "and"
if (x and y) 
    cout << "and: x and y are both non-zero values" << endl;


// Using "&&"
if (x && y) 
    cout << "&&: x and y are both non-zero values" << endl;


// Oops! I meant to type "&&"!
if (x & y) 
    cout << "&: x and y are both non-zero values" << endl;

else 
    cout << "How did I get here?" << endl;

所有三个 if 语句都将编译,但最后一个意味着完全不同的东西和意外!

如果您总是使用and 来表示逻辑与,那么您永远不会不小心输入一个“&”并让您的代码成功编译并以神秘的结果运行。

另一个很好的练习:试着不小心去掉一个“and”字符,看看会发生什么。 ;)

【讨论】:

这并不是问题的真正答案。只是你陈述你觉得更清晰的东西。 OP 询问书面版本是如何工作的,而不是哪个更好。 someone else 已经提出了您要提出的相同观点。 并不是说它真的提供了更多有用的信息,但我会在答案中添加“and&amp;&amp; 在功能上相同”......如果你阅读我的答案,你会看到我说的不是易读性;)【参考方案5】:

尝试搜索此页面以了解逻辑运算符的用法。 &amp;&amp;|| 很容易找到。另一方面,搜索andor 会产生很多误报。

符号版本也可以更好地处理纯文本文件。如果&amp;&amp; 出现在评论或文档中,我立即意识到作者的意思是逻辑运算符。如果 and 出现在文档中,则文本样式可能会告诉我这是什么意思。如果 and 出现在评论中...抱歉,单词识别并没有告诉我它在评论中的功能。

你有没有看到最后一次使用 and,没有文本样式的帮助?

【讨论】:

以上是关于逻辑运算符的书面版本的主要内容,如果未能解决你的问题,请参考以下文章

身份运算符和逻辑运算符

13种Shell逻辑与算术,能写出5种算你赢!

13种Shell逻辑与算术,能写出5种算你赢!

java注释 命名 数据类型 基本类型转换 位运算符 逻辑运算符 三目运算符

java逻辑运算符有哪些

什么是逻辑运算符