5

Guarda questo piccolo frammento.Bitwise e/o con operatore ternario

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

(y è il valore minimo e v è valore rispetto corrente. In questo modo ti fa pensare più facile.)

significato di questo frammento di codice è semplice.
Se il valore corrente v è inferiore al valore minimo , impostare un nuovo valore minimo (y=v). Ma il caso v=0 è escluso.

Poi ho pensato che se il "codice negativo" potesse essere generato, il risultato dovrebbe essere lo stesso. Voglio dire,

y>v&v?y=v:; 

Questo codice dovrebbe fare la stessa cosa. Ma non può essere compilato. L'errore è il seguente.

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

È strano. Penso che due codici siano uguali tra loro. Se l'ultimo operatore ternario è errato, l'ex dovrebbe avere lo stesso problema. Ma non è stato così.

Qualcuno può spiegare perché?

Domanda successiva. Ho inserito un 0 da compilare. y>v&v?y=v:0;
Poi ho ricevuto una risposta falsa. Così ho cambiato & a &&. y>v&&v?y=v:0;
Finalmente ho avuto una risposta giusta. Ma senza questi processi, l'operatore | può fare tutto. Perché?

< informazioni aggiuntive>

La mia versione del compilatore è la seguente.

$ 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 

e compilare opzione:

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

Se si desidera avere un codice di esempio per testare, questo aiuterebbe.

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

(correzione P.S. del mio povero inglese è sempre benvenuta)

+0

@YuHao Questi sono solo per divertimento. So che la leggibilità è molto importante. :) – plhn

+0

[Precisione dell'operatore C++] (http://en.cppreference.com/w/cpp/language/operator_precedence) – CoryKramer

+0

': niente 'non ha senso. hai bisogno di un valore per l'operatore ternario. –

risposta

2

In questo frammento:

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

valore di v viene convertito in bool e annullato con !. Poiché entrambi i lati del bit a bit o | sono bool, | si comporta come il logico o.

Nell'altro caso:

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

non c'è conversione di bool, e invece il risultato di y>v viene convertito in int. Il bit a bit e & fornisce risultati variabili, a seconda del bit più basso di v. Non si comporta come il logico e.
Questo dovrebbe funzionare come l'originale:

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

perché non v'è una conversione a bool.

4

I codici non fanno la stessa cosa, perché le condizioni non sono la negazione di ogni altro.Da provare con 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

+0

molto intuitivo! grazie! – plhn

2

La sintassi dell'operatore condizionale è:

logico-espressione? vera espressione: true-espressione

Nella prima,

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

non trovi il vera espressione. Ricevo il seguente avviso del compilatore con g ++ quando compilato con -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; 

Nella seconda,

y>v&v ? y=v : ; 

non trovi il falso-espressione. Per qualche ragione, g ++ considera questo come un errore invece di un avvertimento.

È possibile risolvere questo problema fornendo un valore fittizio per entrambi.

A proposito, si utilizzano operatori bit a bit | e &. Sono sicuro che è un piccolo errore.

È possibile utilizzare:

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

o

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

Aggiornamento

L'espressione

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

non è Lega l C/C++. È supportato da g ++ come estensione. Più può essere visto a C conditional operator ('?') with empty second parameter.

+1

Wow. Questa è l'estensione gcc. http://stackoverflow.com/questions/10143125/c-conditional-operator-with-empty-second-parameter grazie! – plhn