5

Schauen Sie sich diesen kleinen Ausschnitt an.Bitweise und/oder mit ternärem Operator

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

(y ist Minimalwert und v ist Strom verglichen Wert. So kann man leichter denken würde.)

Diese Bedeutung des Schnipsel einfach ist.
Wenn der aktuelle Wert v kleiner ist als der Minimalwert y, setzen Sie den neuen Mindestwert (y=v). Aber v=0 Fall ist ausgeschlossen.

Dann dachte ich, wenn der "nachteilige Code" generiert werden könnte, sollte das Ergebnis gleich sein. Ich meine,

y>v&v?y=v:; 

Dieser Code sollte die gleiche Sache tun. Aber es kann nicht kompiliert werden. Der Fehler ist wie folgt.

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

Es ist seltsam. Ich denke, dass zwei Codes einander gleich sind. Wenn der zweite ternäre Operator fehlerhaft ist, sollte der vorherige den gleichen Fehler haben. Aber es tat es nicht.

Kann jemand erklären warum?

Nächste Frage. Ich habe eine 0 zum kompilieren eingefügt. y>v&v?y=v:0;
Dann bekam ich eine falsche Antwort. So änderte ich & zu &&. y>v&&v?y=v:0;
Endlich bekam ich eine richtige Antwort. Aber ohne diesen Prozess kann der Operator | alles tun. Warum?

< weitere Informationen>

Mein Compiler-Version ist wie folgt.

$ 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 

Und kompilieren Option:

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

Wenn Sie einen Beispielcode haben wollen zu testen, dies helfen würde.

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

(P. S. Korrektur meiner armen Englisch ist immer willkommen)

+0

@YuHao Diese sind alle nur zum Spaß. Ich weiß, Lesbarkeit ist sehr, sehr wichtig. :) – plhn

+0

[C++ Operator-Vorrang] (http://en.cppreference.com/w/cpp/language/operator_precedence) – CoryKramer

+0

': Nichts macht keinen Sinn. Sie benötigen einen Wert für den ternären Operator. –

Antwort

2

In diesem Auszug:

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

der Wert von v wird in eine bool konvertiert und mit ! negiert. Da beide Seiten der bitweisen oder | Bools sind, verhält sich | wie die logische oder.

Im anderen Fall:

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

gibt es keine Umstellung auf bool und stattdessen das Ergebnis y>v auf int umgewandelt. Die bitweise und & liefert unterschiedliche Ergebnisse, abhängig vom niedrigsten Bit v. Es verhält sich nicht wie das logische und.
Dies sollte wie das Original funktionieren:

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

, weil es eine Konvertierung in bool ist.

4

Die Codes nicht das gleiche tun, weil die Bedingungen nicht die Negation voneinander sind.Versuchen Sie es mit 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

sehr intuitiv! Danke! – plhn

2

Die Syntax des Bedingungsoperator ist:

Logikausdruck? true-Ausdruck: false-Ausdruck

In der ersten,

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

Sie vermissen true-Ausdruck. Ich bekomme die folgende Compiler-Warnung mit g ++, wenn sie mit -Wall kompiliert wird.

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; 

Im zweiten,

y>v&v ? y=v : ; 

Sie vermissen falsch-Ausdruck. Aus irgendeinem Grund behandelt g ++ dies als einen Fehler anstelle einer Warnung.

Sie könnten das beheben, indem Sie für beide einen Dummy-Wert angeben.

Übrigens verwenden Sie die bitweisen Operatoren | und &. Ich bin sicher, das ist ein kleiner Fehler.

können Sie verwenden:

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

oder

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

aktualisieren

Der Ausdruck

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

ist nicht lega l C/C++. Es wird von g ++ als Erweiterung unterstützt. Mehr kann bei C conditional operator ('?') with empty second parameter gesehen werden.

+1

Wow. Dies ist die gcc-Erweiterung. http://stackoverflow.com/questions/10143125/c-conditional-operator-with-empty-second-parameter danke! – plhn