C++中的“OR”运算符

5
这个有什么办法可以完成吗?
if((a || b) == 0) return 1;
return 0;

所以是这样的……如果a或b等于零,那么……但它对我没有起作用。 我的真实代码是:

bool Circle2::contains(Line2 l) {
    if((p1.distanceFrom(l.p1) || p1.distanceFrom(l.p2)) <= r) {
        return 1;
    }
    return 0;
}

9
顺便提一下,你第二个代码的格式很糟糕。很容易错过 return 1; ,并认为 return 0; 是 "then" 子句,而不是隐式的 "else" 子句。 - CodesInChaos
7
请使用return true或者return false语句。虽然编译器可以正确解析此语句,但是如果你要声明布尔类型,请至少使用bool关键字。 - Randolpho
@codeinchaos,我甚至没有看到return 1 - Marlon
你正在寻找ICON编程语言,而不是C ++;这是一种可以编写诸如if (i|j|k) == (10|20)之类的内容的语言,其含义是“i、j或k中的任意一个等于10或20”... http://www.cs.arizona.edu/icon/ - 6502
1
一个很好的基础问题,因为编译器会接受这些片段,然后执行一些初学者可能会感到惊讶的操作。 - dmckee --- ex-moderator kitten
10个回答

20

您需要编写完整的表达式:

(a==0)||(b==0)

而在第二段代码中:

if((p1.distanceFrom(l.p1)<= r) || (p1.distanceFrom(l.p2)<=r) )
    return 1;

如果你写 ((a || b) == 0) 这句话的意思是 "逻辑或 ab 是否等于 0",但这不是你想要的。

另外,值得一提的是: if (BooleanExpression)return true; else return false 可以简写为 return BooleanExpression;


哈哈,这是一场狂奔!为你的超快答题技能加1分。 - Jim Lewis

2

每次都需要单独指定条件:

if (a == 0) || (b == 0))
    bla bla;

当你执行时,
if ((a || b) == 0)
    bla bla;

在IT技术中,“(a || b)”有不同的含义:它表示“如果a或者b中有一个非零(即true),那么这个表达式的结果就是true”。 因此,当你执行“(a||b) == 0”时,你是在检查先前解释过的表达式的结果是否等于零(或false)。


2

模板的乐趣:

template <typename T>
struct or_t
{
  or_t(const T& a, const T& b) : value1(a), value2(b)
  {
  }

  bool operator==(const T& c)
  {
    return value1 == c || value2 == c;
  }

private:
  const T& value1;
  const T& value2;
};

template <typename T>
or_t<T> or(const T& a, const T& b)
{
  return or_t<T>(a, b);
}

正在使用中:

int main(int argc, char** argv)
{
  int a = 7;
  int b = 9;

  if (or(a, b) == 7)
  {
  }

  return 0;
}

它执行与您通常执行的相同比较,但更加方便。


现在尝试短路版本...;-) - 6502

2

C++语言规定||(或)的操作数必须是布尔表达式。

如果p1.distanceFrom(l.p1)不是布尔类型(也就是说,如果distanceFrom返回int、double或某些数字类类型),编译器会尝试将其转换为布尔类型。

对于内置的数字类型,转换规则是:非零值会转换为true,零值会转换为false。如果p1.distanceFrom(l.p1)的类型是类类型Foo,编译器将调用一个(且仅调用一个)用户定义的转换函数,例如Foo::operator bool(),来将表达式的值转换为bool类型。


1

我认为你真正想要的是这样的:

bool Circle2::contains(Line2 l) {
if((p1.distanceFrom(l.p1) <= r) || (p1.distanceFrom(l.p2) <= r)) return 1;
    return 0;
}

1
如果你有很多这样的代码,可以考虑使用一个辅助方法:
bool distanceLE (Point p1, Point p2, double threshold) {
    return (p1.distanceFrom (p2) <= threshold)
}

bool Circle2::contains (Line2 l) {
    return distanceLE (p1, l.p1, r) && distanceLE (p1, l.p2, r);
}

如果你有时使用 <,有时使用 <=,>,>= 等等,也许你应该将运算符作为函数传递。

在某些情况下,你写这个的意图可能是:

if ((a || b) == 0) return 1;
return 0;

可以用按位或来表示:

if ((a | b) == 0) return 1;
return 0;

并简化为

return  ! (a | b);

但是请仔细阅读位运算并进行测试。我很少使用它们,特别是我已经有一段时间没有使用C++了。

请注意,在您的示例1和2之间反转了含义,返回相反的true和false。

当然,按位小于等于没有任何意义。 :)


0

C++并不是那么智能的。你必须手动进行每个比较。

bool Circle2::contains(Line2 l) {
if((p1.distanceFrom(l.p1) <= r) || (p1.distanceFrom(l.p2) <= r)) return 1;
    return 0;
}

0

C++不支持这样的结构。请使用if (a == 0 || b == 0)


2
它们确实有不同的意义。 - Nikita Rybak
1
@NikitaRybak: 我的意思是语义上的。如果ab都为false,(a || b) == 0将为真。 - Cat Plus Plus
是的,我在寻找离散数学中的函数,所以如果a和b都为真,则(a || b) == 0将为真,如果至少有一个为假,则为假。 - Jaanus

0

你的条件应该是 (a == 0 || b == 0) 或者 (p1.distanceFrom(l.p1) <= r || p1.distanceFrom(l.p2)) <= r)


0
你好像知道,在C++中,0代表假,1代表真。基于这个理解,回答你的第一个问题(代码1):
return !(a && b);

如果其中一个布尔值为假,那么`a && b`就是假的,所以`!(a && b)`就是真的,即`1`。否则,a和b都为真,所以`a && b`是真的,所以`!(a && b)`就是假的,即`0`。你也可以这样做(代码2)。
return !a || !b;

但是这个表达式最多执行三个逻辑操作,而第一个表达式最多执行两个,这是较少的。这两个表达式的等价性是德摩根定律之一。
要修复你的第二段代码(代码3):
bool Circle2::contains(Line2 l) {
    return p1.distanceFrom(l.p1) <= r || p1.distanceFrom(l.p2) <= r;
}

如果你想避免双重<= r(代码4):
bool Circle2::contains(Line2 l) {
    for (auto p : { l.p1, l.p2 }) {
        if (p1.distanceFrom(p) <= r) {
            return true;
        }
    }
    return false;
};
for循环初始化一个包含两个值l.p1l.p2的匿名数组,并逐个检查每个值,如果找到满足条件的点,则立即返回true。这意味着它会像||一样进行短路运算。只有在两个点都被发现不满足条件后才会返回false。我建议在这种情况下使用类似于代码3的方式,因为只需要检查两个点,可以用简单的||表达式来实现。在另一种情况下,如果需要检查大量的点,类似于代码4的方式会很有用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接