Посмотрите на этот крошечный фрагмент.
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;
}
(исправление моего плохого английского всегда приветствуется)
В этом фрагменте:
y<v|!v?:y=v;
значение v
превращается в bool
и отрицается с !
, Потому что обе стороны битовой или |
являются bools, |
ведет себя как логический или.
В другом случае:
y>v&v?y=v:0;
нет преобразования в bool
и вместо этого результат y>v
преобразуется в int
, Побитовое и &
дает различные результаты, в зависимости от младшего бита v
, Это не ведет себя как логическое и.
Это должно работать как оригинал:
y>v&!!v?y=v:0;
потому что есть преобразование в bool.
Коды не делают то же самое, потому что условия не являются отрицанием друг друга. Попробуйте это с 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
Синтаксис условного оператора:
логическое выражение? истинное выражение: ложное выражение
В первом
y<v|!v ? : y=v;
вам не хватает истинное выражение. Я получаю следующее предупреждение компилятора с 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 : ;
Вам не хватает ложно-выражение. По какой-то причине g ++ воспринимает это как ошибку, а не как предупреждение.
Вы можете исправить это, предоставив фиктивное значение для них обоих.
Кстати, вы используете побитовые операторы |
а также &
, Я уверен, что это небольшая ошибка.
Ты можешь использовать:
(y<v || !v) ? 0 : y=v;
или же
(y>v && v) ? y=v : 0;
Обновить
Выражение
(y<v || !v) ? : y=v;
не является законным C / C ++. Поддерживается g ++ как расширение. Больше можно увидеть на C условный оператор (‘?’) С пустым вторым параметром.