Warum gibt es in C/C++ keinen ^^-Operator?

Lesezeit: 7 Minuten

Benutzer-Avatar
Zifre

& hat &&. | hat ||. Warum nicht ^ haben ^^?

Ich verstehe, dass es kein Kurzschluss wäre, aber es hätte eine andere Semantik. In C, true ist wirklich jeder Wert ungleich Null. Bitweises XOR ist nicht immer dasselbe wie logisches XOR:

int a=strcmp(str1,str2);// evaluates to 1, which is "true"
int b=strcmp(str1,str3);// evaluates to 2, which is also "true"
int c=a ^^ b; // this would be false, since true ^ true = false
int d=a ^ b; //oops, this is true again, it is 3 (^ is bitwise)

Da kann man sich nicht immer auf ein wahres Wertwesen verlassen 1 oder -1würde nicht a ^^ Betreiber sehr hilfreich sein? Ich muss oft so seltsame Dinge tun:

if(!!a ^ !!b) // looks strange

  • Weil es zu glücklich aussieht. ^_^ Bei C++ geht es um Schmerzen! Optimieren! Optimieren! (Haftungsausschluss: Dies ist ein Witz. Nicht ernst nehmen.)

    – bsniesen

    7. Mai 2009 um 22:02 Uhr

  • Ich bin fasziniert, aber verwirrt … ein logisches XOR a ^ ^ b erfordert, dass alle in a gesetzten Bits in b deaktiviert werden und alle in b gesetzten Bits in a deaktiviert werden?

    – Tom Ritter

    7. Mai 2009 um 22:03 Uhr

  • Ist das nicht eine rhetorische Frage. Müssten die Ersteller der ursprünglichen c/c++-Sprache nicht antworten, um dies wirklich zu beantworten?

    – Tad Donaghe

    7. Mai 2009 um 22:04 Uhr

  • @Terry: Ich denke, es ist etwas rhetorisch, da C nicht plötzlich einen ^^-Operator hinzufügen wird, aber ich bin neugierig darauf und entwerfe eine Programmiersprache. Ich habe mich gefragt, ob ich es aufnehmen sollte. Im Moment ist darin ein ^^-Operator, aber wenn jemand einen guten Grund dagegen angibt, werde ich ihn entfernen.

    – Zifre

    7. Mai 2009 um 22:15 Uhr

  • @Zifre: Ich habe Ihre Frage bearbeitet, um den Leuten klarer zu machen, warum Sie könnte möchte dies tun. Fühlen Sie sich frei, zurückzugehen, wenn Ihnen meine Änderung nicht gefällt. Ich hätte in einem Kommentar vorgeschlagen, aber es gibt keine Formatierung in Kommentaren. Hoffe das hilft.

    – Edi

    7. Mai 2009 um 23:14 Uhr

Benutzer-Avatar
Anziehen

Dennis Ritchie antwortet

Es gibt sowohl historische als auch praktische Gründe, warum es keine gibt ^^ Operator.

Das Praktische ist: Es nützt dem Bediener nicht viel. Der Hauptpunkt von && und || ist ihre Kurzschlussauswertung nicht nur aus Effizienzgründen, sondern immer häufiger auch für Aussagekraft und Korrektheit zu nutzen.
[…]

Dagegen ein ^^ Der Operator würde immer die Auswertung beider Arme des Ausdrucks erzwingen, also gibt es keinen Effizienzgewinn. Darüber hinaus Situationen, in denen ^^ wirklich erforderlich ist, sind ziemlich selten, obwohl Beispiele geschaffen werden können. Diese Situationen werden seltener und seltsamer, wenn Sie den Operator stapeln —

if (cond1() ^^ cond2() ^^ cond3() ^^ ...) ...

macht die Folge genau dann, wenn eine ungerade Anzahl der condx()s sind wahr. Im Gegensatz dazu die && und || Analoga bleiben ziemlich plausibel und nützlich.

  • Wow, ich hatte nicht erwartet, dass Dennis Rithchie meine Frage beantwortet :). Siehe Terry Donaghes Kommentar. Er gibt tatsächlich einige sehr gute Punkte. +1

    – Zifre

    7. Mai 2009 um 22:48 Uhr

Benutzer-Avatar
Johannes Rasch

Technisch existiert bereits einer:

a != b

da dies als wahr ausgewertet wird, wenn sich der Wahrheitswert der Operanden unterscheidet.

Bearbeiten:

Voltes Kommentar:

(!a) != (!b)

ist richtig, weil meine Antwort oben nicht funktioniert int Typen. Ich werde meine löschen, wenn er seine Antwort hinzufügt.

Nochmals editieren:

Vielleicht vergesse ich etwas von C++, aber je mehr ich darüber nachdenke, desto mehr frage ich mich, warum Sie jemals schreiben würden if (1 ^ 2) an erster Stelle. Der Zweck für ^ besteht darin, zwei Zahlen zusammenzuschließen (was zu einer anderen Zahl ausgewertet wird), sie nicht in boolesche Werte umzuwandeln und ihre Wahrheitswerte zu vergleichen.

Dies scheint eine seltsame Annahme für einen Sprachdesigner zu sein.

  • Für nicht-boolesche Eingaben sollten Sie verwenden ((!!a) != (!!b)) (mit zusätzlichen Klammern für Paranoia!).

    – kquinn

    7. Mai 2009 um 22:05 Uhr

  • Natürlich funktioniert dies nur bei booleschen Typen, daher benötigen Sie eine Umwandlung, um sie wie im Beispiel des OP mit ints zu verwenden. +1 sowieso.

    – rméador

    7. Mai 2009 um 22:06 Uhr

  • ‘(!a) != (!b)’ hat den gleichen Effekt.

    – Simon Breitkopf

    7. Mai 2009 um 22:07 Uhr

  • Ich habe diese Frage tatsächlich falsch gelesen, ich habe die Kommentare in seinem Code gesehen (die wahr und falsch sagen), aber den int-Typ verpasst – ich muss euch beim Casting vertrauen, obwohl mein C++ ein wenig eingerostet ist

    – Johannes Rasch

    7. Mai 2009 um 22:10 Uhr

  • Nein, 1 != 2 ist wahr, wenn 1 ^^ 2 falsch wäre. Am Ende müssen Sie es in !s einschließen, in diesem Fall denke ich, dass !!1 ^ !!2 viel klarer wäre.

    – Zifre

    7. Mai 2009 um 22:12 Uhr

Benutzer-Avatar
Eddi

Für Nicht-bool Operanden, ich denke, was Sie wollen, ist für a ^^ b zu bewerten als:

(a != 0) ^ (b != 0)

Nun, Sie haben die obige Option und Sie haben einige Optionen, die in anderen Antworten aufgeführt sind.

Der Betreiber ^^ wäre überflüssig für bool Operanden. Wenn wir nur über boolesche Operanden sprechen, tun wir das der Argumentation halber so ^ war bitweise-nur und das ^^ existierte als logisches XOR. Sie haben dann diese Auswahlmöglichkeiten:

  • & – Bitweises UND — wertet immer beide Operanden aus
  • && – Logisches UND — wertet nicht immer beide Operanden aus
  • | – Bitweises ODER — wertet immer beide Operanden aus
  • || – Logisches ODER — wertet nicht immer beide Operanden aus
  • ^ – Bitweises XOR — muss immer beide Operanden auswerten
  • ^^ – Logisches XOR — muss immer beide Operanden auswerten

Warum haben sie nicht geschaffen ^^ um numerische Werte im Wesentlichen in umzuwandeln bools und dann handeln als ^? Das ist eine gute Frage. Vielleicht, weil es potenziell verwirrender ist als && und ||vielleicht weil Sie das Äquivalent von leicht konstruieren können ^^ mit anderen Betreibern.

  • Sein Punkt ist, dass, wenn Sie die Operation (1 ^^ 2) durchführen würden, sie als falsch ausgewertet würde, wenn er glaubt, dass sie wie (1 ^^ 2) als wahr ausgewertet werden sollte. Ich sage nicht, dass ich zustimme, ich weise nur darauf hin, dass es eigentlich nicht überflüssig ist.

    – Joseph

    7. Mai 2009 um 22:08 Uhr

Benutzer-Avatar
Jay

Ich kann nicht sagen, was in den Köpfen von Kernighan und Ritchie vorging, als sie C erfanden, aber Sie haben kurz darauf verwiesen, dass es keinen Kurzschluss geben würde, und ich vermute, das ist der Grund: Es ist nicht möglich, es zu implementieren es konsequent. Sie können XOR nicht wie AND und OR kurzschließen, daher könnte ^^ && und || nicht vollständig parallel sein. Die Autoren könnten also entschieden haben, dass es schlimmer wäre, eine Operation durchzuführen, die wie eine Parallele zu den anderen aussieht, aber nicht ganz so ist, als sie überhaupt nicht zu haben.

Persönlich der Hauptgrund, warum ich && und || verwende ist eher für den Kurzschluss als für den nicht-bitweisen. Eigentlich benutze ich die bitweisen Operatoren überhaupt sehr selten.

Eine weitere Problemumgehung für die oben geposteten (auch wenn dafür ein weiterer Zweig im Code erforderlich ist) wäre:

if ( (a? !b : b ) )

das ist äquivalent zu xor.

  • Ja, natürlich sind sie Problemumgehungen, aber ich denke, ein echter ^^-Operator würde Ihre Absichten klarer darstellen. Dein Beispiel ist nicht so offensichtlich.

    – Zifre

    8. Mai 2009 um 13:27 Uhr

Benutzer-Avatar
neues Konto

Auf Java die ^ Der Operator führt tatsächlich ein logisches XOR aus, wenn er auf zwei boolesche Operanden angewendet wird (genau wie & und | in Java logisches UND bzw. ODER nicht kurzschließen, wenn sie auf boolesche Werte angewendet werden). Der Hauptunterschied zu C/C++ besteht darin, dass Sie in C/C++ ganze Zahlen und boolesche Werte mischen können, während Java dies nicht tut.

Aber ich denke, es ist sowieso eine schlechte Praxis, ganze Zahlen als boolesche Werte zu verwenden. Wenn Sie logische Operationen ausführen möchten, sollten Sie bei beiden bleiben bool Werte oder ganze Zahlen, die entweder 0 oder 1 sind. Dann ^ funktioniert gut als logisches XOR.

Eine analoge Frage wäre zu fragen, wie würden Sie logisches UND und ODER in C / C++ nicht kurzschließen? Die übliche Antwort ist die Verwendung von & und | Betreiber bzw. Aber auch dies hängt von den Werten ab bool oder entweder 0 oder 1. Wenn Sie ganzzahlige Werte zulassen, funktioniert dies auch nicht.

  • Ja, natürlich sind sie Problemumgehungen, aber ich denke, ein echter ^^-Operator würde Ihre Absichten klarer darstellen. Dein Beispiel ist nicht so offensichtlich.

    – Zifre

    8. Mai 2009 um 13:27 Uhr

Benutzer-Avatar
entspannen

Egal ob dafür oder dagegen ^^ als Operator nimmst du zB mit strcmp() saugt. Es gibt keinen Wahrheitswert (wahr oder falsch) zurück, es gibt eine Beziehung zwischen seinen Eingaben zurück, die als Ganzzahl codiert ist.

Sicher, jede ganze Zahl kann in C als Wahrheitswert interpretiert werden, in diesem Fall ist 0 “falsch” und alle anderen Werte sind “wahr”, aber das ist das Gegenteil von was strcmp() kehrt zurück.

Ihr Beispiel sollte beginnen:

int a = strcmp(str1, str2) == 0; // evaluates to 0, which is "false"
int b = strcmp(str1, str3) == 0; // evaluates to 0, which is also "false"

Sie müssen den Rückgabewert mit 0 vergleichen, um ihn in einen richtigen booleschen Wert umzuwandeln, der angibt, ob die Zeichenfolgen gleich waren oder nicht.

Mit “richtigen” booleschen Werten, die kanonisch als 0 oder 1 dargestellt werden, ist das bitweise ^ Operator funktioniert auch viel besser …

1093630cookie-checkWarum gibt es in C/C++ keinen ^^-Operator?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy