Побитовый и / или с троичным оператором

Посмотрите на этот крошечный фрагмент.

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;
}

(исправление моего плохого английского всегда приветствуется)

5

Решение

В этом фрагменте:

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.

2

Другие решения

Коды не делают то же самое, потому что условия не являются отрицанием друг друга. Попробуйте это с 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

4

Синтаксис условного оператора:

логическое выражение? истинное выражение: ложное выражение

В первом

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 условный оператор (‘?’) С пустым вторым параметром.

2
По вопросам рекламы [email protected]