Doppelausruf definieren?

7

Ich verstehe, was ein doppeltes Ausrufezeichen tut (oder ich glaube, ich verstehe), aber ich bin mir nicht sicher, wie es bei einem zufälligen Objekt definiert ist. Zum Beispiel im folgenden Codefragment:

%Vor%

Woher weiß ich, welchen Wert das doppelte Ausrufezeichen haben wird? Mit anderen Worten, konvertiert es immer zu wahr? falsch? oder können Sie ein Verhalten dafür definieren, zum Beispiel eine Methode ausführen, um das Ergebnis zu bestimmen (wie kann das Objekt in dieser Situation handeln)? Ich bin etwas verwirrt über dieses Stück Code aufgrund all dieser Ausrufe Sachen weiter. Jede Erklärung ist willkommen.

Ich hoffe, ich war klar und danke.

    
Cemre 07.07.2012, 12:00
quelle

7 Antworten

13

a ist ein Zeiger. In C ++ ist nullptr als ungültiger Zeiger definiert. !pointer verwandelt einen nullptr Zeiger in true und einen nicht nullptr Zeiger in false . !boolean verwandelt true in false und false in true . Es wird immer funktionieren.

!(!a) ist eine nützliche Methode, um darüber nachzudenken.

    
Jeffery Thomas 07.07.2012, 12:03
quelle
6

Betrachte es nicht als "doppeltes Ausrufezeichen", sondern stelle es als zwei getrennte Operatoren dar, von denen einer auf dem Ergebnis des anderen läuft.

Für alle primitiven Typen wird es "funktionieren". !a entspricht a == 0 , also entspricht !!a !(a == 0) , was wiederum a != 0 entspricht.

Für benutzerdefinierte Typen wird es nicht kompiliert, wenn sie operator ! nicht überladen. Aber in diesem Fall könnte das Verhalten fast alles sein.

    
Oliver Charlesworth 07.07.2012 12:05
quelle
2

!! ist kein einzelnes Token in C ++ und löst einfach den Operator ! zweimal.

Da a ein Zeiger und kein Objekt des Klassentyps ist, kann ! nicht überladen werden. Es ist so definiert, dass true zurückgegeben wird, wenn a ein Nullzeiger und false andernfalls ist.

Die zweite Anwendung von ! negiert einfach das Ergebnis der ersten ! .

Der Ausdruck !!a entspricht a != 0 .

    
Charles Bailey 07.07.2012 12:10
quelle
1

Der Code ist schrecklich kompliziert. In Wirklichkeit möchten Sie testen, ob die Methode getAssigment erfolgreich ist und ob der zugewiesene Zeiger nicht null ist.

Der Code testet dies, wenn auch in einer verschlungenen Art und Weise, indem er die schwache Typisierung ausnutzt, anstatt zu versuchen, die Explicitness und C ++ starke Typisierung einzubeziehen. Als Konsequenz ist es kein idiomatisches C ++ und etwas schwieriger zu verstehen als nötig.

Verwenden Sie insbesondere nicht !!a in C ++. Dies ist ein etabliertes Idiom in schwach typisierten Sprachen wie JavaScript, um einen Wert in einen booleschen Typ zu zwingen. Aber in C ++ ist dies nicht üblich.

Es ist nicht klar, was der Code tut, da hasSolution nicht definiert oder verwendet wird. Ich vermute jedoch , dass der Code dem folgenden entspricht:

%Vor%

(Vor C ++ 11 müssen Sie 0 anstelle von nullptr schreiben.)

Dieser Code zeigt jedoch immer noch ein schlechtes Design: Warum wird a als Referenz übergeben? Warum ist es nicht der Rückgabewert? Schlimmer noch, a wird nie benutzt, also unnötig. Wenn a tatsächlich unnötig ist, sollte es komplett weggelassen werden. Wenn es notwendig ist, sollte es der Rückgabewert sein. Mit anderen Worten, der Prototyp von getAssignment sollte wie folgt aussehen:

%Vor%

Und es sollte einfach wie folgt verwendet werden:

%Vor%

Außerdem vermute ich, dass dieser Code dem rohen Zeiger a tatsächlich Speicherbesitz zuweist. Dies wird in modernem C ++ dringend empfohlen . Verwenden Sie entweder keine Zeiger oder einen intelligenten Zeiger.

    
Konrad Rudolph 07.07.2012 13:00
quelle
0
%Vor%     
ForEveR 07.07.2012 12:02
quelle
0

Es gibt kein "!!" Operator, also in der Tat entspricht die Aussage:

hasSolution =! (! a);

Zuerst wird der Operator! () für den Ausdruck "a" aufgerufen, dann wird ein anderer Operator! () für das Ergebnis aufgerufen. Im Falle unseres Codes ist "a" ein Zeiger auf Zuordnung. C ++ definiert einen Sonderfall für die Verwendung von operator! () Für einen Zeigertyp: Es gibt ein Bool zurück, das wahr ist, wenn der Zeiger Null ist und andernfalls false. Kurz gesagt, das gleiche wie der Ausdruck (a == 0). Das Aufrufen von operator! () Auf das Ergebnis von (! A), was ein bool ist, kehrt einfach das Ergebnis zurück, d. H. Gibt wahr zurück, wenn (! A) falsch und falsch ist, wenn (! A) wahr ist.

Zusammenfassend ergibt (!! a) dasselbe Ergebnis wie (a! = 0). Dies liegt daran, dass "a" ein Zeiger ist.

    
Frederic Lachasse 07.07.2012 12:25
quelle
0

Der einfachste Weg, sich an die doppelte Negation zu erinnern, ist, a! = 0 auf 1 und a == 0 auf 0 zu beschränken. Das ist im booleschen Kontext (d. H. C ++) wahr oder falsch.

    
rurban 07.07.2012 18:58
quelle

Tags und Links