5

看看这个小片段。

y<v|!v?:y=v;

y是最小值,v是当前比较值。这样会让你更容易思考。)

这个片段的意思很简单。
如果当前值v小于最小值y,则设置新的最小值(y=v)。但是v=0情况除外。

然后我想如果可以生成“不利代码”,结果应该是一样的。我是说,

y>v&v?y=v:;

这段代码应该做同样的事情。但它无法编译。错误如下。

error: expected expression
  for(int v: a) v=abs(a[i]-v), x>v?:x=v, y>v&v?y=v:;
                                                   ^

有点奇怪。我认为两个代码彼此相同。如果后一个三元运算符是错误的,前一个应该有同样的问题。但它没有。

有人可以解释为什么吗?

下一个问题。我插入了一个0来编译。y>v&v?y=v:0;
然后我得到了一个错误的答案。所以我&改为&&. y>v&&v?y=v:0;
最后我得到了正确的答案。但是如果没有这些过程,使用|操作符就可以完成所有工作。为什么?

<附加信息>

我的编译器版本如下。

$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.4.0
Thread model: posix

并编译选项:

g++ -std=c++11 my.cpp

如果你想有一个示例代码来测试,这会有所帮助。

#include <iostream>
#include <vector>
using namespace std;
int working(int i, vector<int> a) {
  int y=INT_MAX;
  for(int v: a) v=abs(a[i]-v), y<v|!v?:y=v;
  return y;
}

int not_working(int i, vector<int> a) {
  int y=INT_MAX;
  for(int v: a) v=abs(a[i]-v), y>v&v?y=v:0;
  return y;
}

int main() {
  vector<int> b({-5,-2,2,7});
  cout << working(2, b) << endl;
  cout << not_working(2,b) << endl;
  return 0;
}

(总是欢迎对我糟糕的英语进行 ps 更正)

4

3 回答 3

4

代码不做同样的事情,因为条件不是彼此的否定。试试看y == 3, v == 2

y < v | !v=> 3 < 2 | !2=> false | !true=> false | false=> 0 | 0=>0

y > v & v=> 3 > 2 & 2=> true & 2=> 1 & 2=>0

于 2015-08-17T14:38:53.460 回答
2

在这个片段中:

y<v|!v?:y=v;

的值v被转换为 abool并用 求反!。因为按位或的两边|都是布尔值,|所以表现得像逻辑或。

在另一种情况下:

y>v&v?y=v:0;

没有转换为bool,而是将结果y>v转换为int。逐位 和&给出不同的结果,具体取决于v. 它的行为不像逻辑与。
这应该像原来的那样工作:

y>v&!!v?y=v:0;

因为有一个布尔转换。

于 2015-08-17T14:48:39.683 回答
2

条件运算符的语法是:

逻辑表达式 ? 真表达式:假表达式

在第一个中,

y<v|!v ? : y=v;

您缺少true-expression。使用 g++ 编译时,我收到以下编译器警告-Wall

socc.cc: In function ‘int main()’:
socc.cc:14:12: warning: the omitted middle operand in ?: will always be ‘true’, suggest explicit middle operand [-Wparentheses]
    y<v||!v?:y=v;

在第二个中,

y>v&v ? y=v : ;

您缺少false-expression。出于某种原因,g++ 将此视为错误而不是警告。

您可以通过为它们提供一个虚拟值来解决这个问题。

顺便说一句,您正在使用按位运算符|&. 我确信这是一个小错误。

您可以使用:

(y<v || !v) ?  0 : y=v;

或者

(y>v && v) ? y=v : 0;

更新

表达方式

(y<v || !v) ? : y=v;

不是合法的 C/C++。g++ 支持它作为扩展。在第二个参数为空的 C 条件运算符 ('?')中可以看到更多信息。

于 2015-08-17T14:57:31.343 回答