c++ - 如果在我的三角形练习中给出括号错误的语句

学习 C++ 并做一个基本的三角形练习。

如果我做的一切都正确,任何人都可以检查我的代码并解释为什么我会收到这个错误:建议在“||”中的“&&”周围加上括号

#include <iostream>

int main()
{
    // enter 3 numbers for sides of triangle
    int a, b, c;
    std::cout << "Input three numbers: " << std::endl;
    std::cin >> a;
    std::cin >> b; 
    std::cin >> c;
  
    // check what kind of traingle it is and output result
    if(a == b  && b == c){
        std::cout << "You have an equalateral triangle." << std::endl;
    }else if(a == b && b !=c || a!=b && b==c || a==c && b!=c){
        std::cout << "You have an iso triangle." << std::endl;
    }else{
        std::cout << "You have an scalene triangle." << std::endl;
    } 
}

回答1

您收到的错误消息是 Clang 可以生成的诊断信息

如果这些显示为错误,您可能在编译器选项中启用了 -Werror。您可以删除该标志以停止将警告升级为错误。或者,如果您不希望它针对(说实话)非常虚假的诊断发出警告(升级为错误),您可以将 -Wno-logical-op-parentheses 添加到编译器选项中。

至于为什么首先生成此诊断: &&|| 之间的运算符优先级并不总是很明显,尤其是对于新程序员而言,Clang 建议您明确指定运算符优先级以确保您'写的是你想要的。所以它要求你像这样重写这些行:

if(a == b && b == c) {
    std::cout << "You have an equalateral triangle." << std::endl;
} else if((a == b && b != c) || (a != b && b == c) || (a == c && b != c)) {
    std::cout << "You have an iso triangle." << std::endl;
} else {
    std::cout << "You have an scalene triangle." << std::endl;
}

额外的括号使警告消失。

据我所知,您的代码中实际上没有逻辑错误(布尔逻辑的行为与您期望的一样),实际上,如果您将此代码发送到不同的编译器,它们会毫无问题地编译它。所以这实际上只是 Clang 的一个特殊怪癖。

回答2

编译器建议您使用括号使第二个 if 语句更清晰/更易于解析。

特别是,您应该使用括号对 || 语句中的 && 语句进行分组。也就是改变这段代码

(a == b && b !=c || a != b && b == c || a == c && b != c)

((a == b && b != c) || (a != b && b == c) || (a == c && b != c))

值得注意的是,这是一个“风格错误”;第一种形式并不是严格不正确的代码(实际上,在没有编译器标志的情况下,我能够很好地编译和运行它),但是以第二种方式编写它是一种很好的做法。

如果您将 -Wall 标志传递给您的编译器(或者更具体地说,在这种情况下是 -Wlogical-op-parentheses 标志),这将显示为警告。传递 -Werror 会将这些警告更改为错误,这里似乎就是这种情况。最好同时使用 -Wall-Werror,因为编译器会指出类似这样的潜在清晰度问题,并强制您在继续编译之前修复它们。

回答3

这肯定会产生分歧,但我认为在您尝试将任何代码推送到生产环境之前,您需要充分了解 C++ 语法。

事实上,|| 的优先级低于 &&。这应该是你的第二天性,就像二元运算符 +* 的优先级应该是一样。用括号强调显而易见的东西会引入噪音并使您的代码更难阅读。我建议您关闭该特定警告,然后按。

请注意,在您的特定情况下,尽管第二个条件简化为

else if (a == b || a == c || b == c)

因为你已经消除了等边的可能性。同样,一些软件公司坚持认为 if 语句都是互斥的,因为它们可以在不破坏代码的情况下任意重新排序。恐怕还有更多的意见。

相似文章